Commit 7339b650 authored by Steven杜宇's avatar Steven杜宇

Merge branch 'plan' of http://gitlab.galaxy-immi.com/mobile-group/galaxy-iOS into plan

# Conflicts:
#	galaxy/galaxy/Classes/Tools/NetWork/YHAllApiName.swift
parents 73e743f8 81b75573
...@@ -1177,6 +1177,11 @@ ...@@ -1177,6 +1177,11 @@
04A750DA2D94FDDF00974E5F /* YHSurveyMatchingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750D92D94FDDF00974E5F /* YHSurveyMatchingViewController.swift */; }; 04A750DA2D94FDDF00974E5F /* YHSurveyMatchingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750D92D94FDDF00974E5F /* YHSurveyMatchingViewController.swift */; };
04A750E82D952F2E00974E5F /* survey_match_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 04A750E72D952F2E00974E5F /* survey_match_success.json */; }; 04A750E82D952F2E00974E5F /* survey_match_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 04A750E72D952F2E00974E5F /* survey_match_success.json */; };
04A750E92D952F2E00974E5F /* survey_file_scan.json in Resources */ = {isa = PBXBuildFile; fileRef = 04A750E62D952F2E00974E5F /* survey_file_scan.json */; }; 04A750E92D952F2E00974E5F /* survey_file_scan.json in Resources */ = {isa = PBXBuildFile; fileRef = 04A750E62D952F2E00974E5F /* survey_file_scan.json */; };
04A750EB2D963AFE00974E5F /* YHSurveyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750EA2D963AFE00974E5F /* YHSurveyViewModel.swift */; };
04A750ED2D963BE900974E5F /* YHSurveyContentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750EC2D963BE900974E5F /* YHSurveyContentModel.swift */; };
04A750EF2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750EE2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift */; };
04A750F12D9AAD0300974E5F /* YHSurveyResponseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750F02D9AAD0300974E5F /* YHSurveyResponseModel.swift */; };
04A750F32D9AB95300974E5F /* YHSurveyRenewalPlanState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04A750F22D9AB95300974E5F /* YHSurveyRenewalPlanState.swift */; };
04AE200F2D12CFAF00891D24 /* YHGCMineSchemeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FF82D12CFAF00891D24 /* YHGCMineSchemeViewController.swift */; }; 04AE200F2D12CFAF00891D24 /* YHGCMineSchemeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FF82D12CFAF00891D24 /* YHGCMineSchemeViewController.swift */; };
04AE20102D12CFAF00891D24 /* YHGCApplicationTypeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFD2D12CFAF00891D24 /* YHGCApplicationTypeController.swift */; }; 04AE20102D12CFAF00891D24 /* YHGCApplicationTypeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFD2D12CFAF00891D24 /* YHGCApplicationTypeController.swift */; };
04AE20112D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFE2D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift */; }; 04AE20112D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFE2D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift */; };
...@@ -2480,6 +2485,11 @@ ...@@ -2480,6 +2485,11 @@
04A750D92D94FDDF00974E5F /* YHSurveyMatchingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyMatchingViewController.swift; sourceTree = "<group>"; }; 04A750D92D94FDDF00974E5F /* YHSurveyMatchingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyMatchingViewController.swift; sourceTree = "<group>"; };
04A750E62D952F2E00974E5F /* survey_file_scan.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = survey_file_scan.json; sourceTree = "<group>"; }; 04A750E62D952F2E00974E5F /* survey_file_scan.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = survey_file_scan.json; sourceTree = "<group>"; };
04A750E72D952F2E00974E5F /* survey_match_success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = survey_match_success.json; sourceTree = "<group>"; }; 04A750E72D952F2E00974E5F /* survey_match_success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = survey_match_success.json; sourceTree = "<group>"; };
04A750EA2D963AFE00974E5F /* YHSurveyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyViewModel.swift; sourceTree = "<group>"; };
04A750EC2D963BE900974E5F /* YHSurveyContentModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyContentModel.swift; sourceTree = "<group>"; };
04A750EE2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveySubmitRequestModel.swift; sourceTree = "<group>"; };
04A750F02D9AAD0300974E5F /* YHSurveyResponseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyResponseModel.swift; sourceTree = "<group>"; };
04A750F22D9AB95300974E5F /* YHSurveyRenewalPlanState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHSurveyRenewalPlanState.swift; sourceTree = "<group>"; };
04AE1FF82D12CFAF00891D24 /* YHGCMineSchemeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCMineSchemeViewController.swift; sourceTree = "<group>"; }; 04AE1FF82D12CFAF00891D24 /* YHGCMineSchemeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCMineSchemeViewController.swift; sourceTree = "<group>"; };
04AE1FFA2D12CFAF00891D24 /* YHGCSchemeTableHeadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCSchemeTableHeadView.swift; sourceTree = "<group>"; }; 04AE1FFA2D12CFAF00891D24 /* YHGCSchemeTableHeadView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCSchemeTableHeadView.swift; sourceTree = "<group>"; };
04AE1FFD2D12CFAF00891D24 /* YHGCApplicationTypeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCApplicationTypeController.swift; sourceTree = "<group>"; }; 04AE1FFD2D12CFAF00891D24 /* YHGCApplicationTypeController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YHGCApplicationTypeController.swift; sourceTree = "<group>"; };
...@@ -6808,7 +6818,11 @@ ...@@ -6808,7 +6818,11 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04D8FF582D925E6700703C75 /* YHPlanModel.swift */, 04D8FF582D925E6700703C75 /* YHPlanModel.swift */,
04A750EE2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift */,
04A750D32D93DFED00974E5F /* YHSurveyQuestionType.swift */, 04A750D32D93DFED00974E5F /* YHSurveyQuestionType.swift */,
04A750EC2D963BE900974E5F /* YHSurveyContentModel.swift */,
04A750F02D9AAD0300974E5F /* YHSurveyResponseModel.swift */,
04A750F22D9AB95300974E5F /* YHSurveyRenewalPlanState.swift */,
); );
path = M; path = M;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -6817,6 +6831,7 @@ ...@@ -6817,6 +6831,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04D8FF5A2D925E8100703C75 /* YHPlanViewModel.swift */, 04D8FF5A2D925E8100703C75 /* YHPlanViewModel.swift */,
04A750EA2D963AFE00974E5F /* YHSurveyViewModel.swift */,
); );
path = VM; path = VM;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -7169,6 +7184,7 @@ ...@@ -7169,6 +7184,7 @@
045C0FBF2D12CA5F00BD2DC0 /* YHMyLikeViewController.swift in Sources */, 045C0FBF2D12CA5F00BD2DC0 /* YHMyLikeViewController.swift in Sources */,
045C0FC02D12CA5F00BD2DC0 /* YHHomeCollectionLayout.swift in Sources */, 045C0FC02D12CA5F00BD2DC0 /* YHHomeCollectionLayout.swift in Sources */,
045C0FC12D12CA5F00BD2DC0 /* YHOffivialApprovalGuildLineCheckView.swift in Sources */, 045C0FC12D12CA5F00BD2DC0 /* YHOffivialApprovalGuildLineCheckView.swift in Sources */,
04A750ED2D963BE900974E5F /* YHSurveyContentModel.swift in Sources */,
045C0FC22D12CA5F00BD2DC0 /* YHIncomeTypesCell.swift in Sources */, 045C0FC22D12CA5F00BD2DC0 /* YHIncomeTypesCell.swift in Sources */,
045C0FC32D12CA5F00BD2DC0 /* YHIncomeRecordSummaryCell.swift in Sources */, 045C0FC32D12CA5F00BD2DC0 /* YHIncomeRecordSummaryCell.swift in Sources */,
045C0FC42D12CA5F00BD2DC0 /* YHSheetPickerViewType.swift in Sources */, 045C0FC42D12CA5F00BD2DC0 /* YHSheetPickerViewType.swift in Sources */,
...@@ -7683,6 +7699,7 @@ ...@@ -7683,6 +7699,7 @@
045C11752D12CA5F00BD2DC0 /* YHAIProductCell.swift in Sources */, 045C11752D12CA5F00BD2DC0 /* YHAIProductCell.swift in Sources */,
045C11762D12CA5F00BD2DC0 /* YHHKRecordsHeaderCell.swift in Sources */, 045C11762D12CA5F00BD2DC0 /* YHHKRecordsHeaderCell.swift in Sources */,
045C11772D12CA5F00BD2DC0 /* YHWorkMessageSelectTableViewCell.swift in Sources */, 045C11772D12CA5F00BD2DC0 /* YHWorkMessageSelectTableViewCell.swift in Sources */,
04A750F32D9AB95300974E5F /* YHSurveyRenewalPlanState.swift in Sources */,
045C11782D12CA5F00BD2DC0 /* YHResignGuidelinesViewModel.swift in Sources */, 045C11782D12CA5F00BD2DC0 /* YHResignGuidelinesViewModel.swift in Sources */,
045C11792D12CA5F00BD2DC0 /* YHFormItemDoubleChoiceCell.swift in Sources */, 045C11792D12CA5F00BD2DC0 /* YHFormItemDoubleChoiceCell.swift in Sources */,
045C117A2D12CA5F00BD2DC0 /* YHEmailInputAlertView.swift in Sources */, 045C117A2D12CA5F00BD2DC0 /* YHEmailInputAlertView.swift in Sources */,
...@@ -7771,6 +7788,7 @@ ...@@ -7771,6 +7788,7 @@
045C11C62D12CA5F00BD2DC0 /* YHListViewController.swift in Sources */, 045C11C62D12CA5F00BD2DC0 /* YHListViewController.swift in Sources */,
045C11C72D12CA5F00BD2DC0 /* YHWorkExperiencePositionTableViewCell.swift in Sources */, 045C11C72D12CA5F00BD2DC0 /* YHWorkExperiencePositionTableViewCell.swift in Sources */,
045C11C82D12CA5F00BD2DC0 /* YHOrderSearchViewController.swift in Sources */, 045C11C82D12CA5F00BD2DC0 /* YHOrderSearchViewController.swift in Sources */,
04A750EF2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift in Sources */,
045C11C92D12CA5F00BD2DC0 /* YHNoDataTipsView.swift in Sources */, 045C11C92D12CA5F00BD2DC0 /* YHNoDataTipsView.swift in Sources */,
045C11CA2D12CA5F00BD2DC0 /* YHHKRecordsInfoItemCell.swift in Sources */, 045C11CA2D12CA5F00BD2DC0 /* YHHKRecordsInfoItemCell.swift in Sources */,
04D8FF792D97BDBD00703C75 /* YHPlanShareViewController.swift in Sources */, 04D8FF792D97BDBD00703C75 /* YHPlanShareViewController.swift in Sources */,
...@@ -8055,6 +8073,7 @@ ...@@ -8055,6 +8073,7 @@
045C12B22D12CA5F00BD2DC0 /* YHResignUploadDetailViewModel.swift in Sources */, 045C12B22D12CA5F00BD2DC0 /* YHResignUploadDetailViewModel.swift in Sources */,
045C12B32D12CA5F00BD2DC0 /* YHFamilyInfoConfirmViewModel.swift in Sources */, 045C12B32D12CA5F00BD2DC0 /* YHFamilyInfoConfirmViewModel.swift in Sources */,
045C12B42D12CA5F00BD2DC0 /* YHLifeDetailViewController.swift in Sources */, 045C12B42D12CA5F00BD2DC0 /* YHLifeDetailViewController.swift in Sources */,
04A750F12D9AAD0300974E5F /* YHSurveyResponseModel.swift in Sources */,
045C12B52D12CA5F00BD2DC0 /* YHIncomeRecordWorkExperienceViewController.swift in Sources */, 045C12B52D12CA5F00BD2DC0 /* YHIncomeRecordWorkExperienceViewController.swift in Sources */,
045C12B62D12CA5F00BD2DC0 /* YHMyLikeViewModel.swift in Sources */, 045C12B62D12CA5F00BD2DC0 /* YHMyLikeViewModel.swift in Sources */,
045C12B72D12CA5F00BD2DC0 /* YHCertificateUploadSheetView.swift in Sources */, 045C12B72D12CA5F00BD2DC0 /* YHCertificateUploadSheetView.swift in Sources */,
...@@ -8136,6 +8155,7 @@ ...@@ -8136,6 +8155,7 @@
045C12F92D12CA5F00BD2DC0 /* YHEducationCertificateConfirmCell.swift in Sources */, 045C12F92D12CA5F00BD2DC0 /* YHEducationCertificateConfirmCell.swift in Sources */,
045C12FA2D12CA5F00BD2DC0 /* YHAcademicPreviewModel.swift in Sources */, 045C12FA2D12CA5F00BD2DC0 /* YHAcademicPreviewModel.swift in Sources */,
045C12FB2D12CA5F00BD2DC0 /* YHHomeIdentityViewController.swift in Sources */, 045C12FB2D12CA5F00BD2DC0 /* YHHomeIdentityViewController.swift in Sources */,
04A750EB2D963AFE00974E5F /* YHSurveyViewModel.swift in Sources */,
045C12FC2D12CA5F00BD2DC0 /* YHAdopterAddModel.swift in Sources */, 045C12FC2D12CA5F00BD2DC0 /* YHAdopterAddModel.swift in Sources */,
045C12FD2D12CA5F00BD2DC0 /* YHOtherLoginViewController.swift in Sources */, 045C12FD2D12CA5F00BD2DC0 /* YHOtherLoginViewController.swift in Sources */,
045C12FE2D12CA5F00BD2DC0 /* YHInformationAuthorizationStepTwoViewController.swift in Sources */, 045C12FE2D12CA5F00BD2DC0 /* YHInformationAuthorizationStepTwoViewController.swift in Sources */,
......
...@@ -42,7 +42,8 @@ class YHHomeBannerView: UIView { ...@@ -42,7 +42,8 @@ class YHHomeBannerView: UIView {
} }
} }
private let viewModel = YHLiveSalesViewModel() private lazy var viewModel = YHLiveSalesViewModel()
private lazy var surveyViewModel = YHSurveyViewModel()
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
...@@ -113,6 +114,22 @@ private extension YHHomeBannerView { ...@@ -113,6 +114,22 @@ private extension YHHomeBannerView {
YHOneKeyLoginManager.shared.oneKeyLogin() YHOneKeyLoginManager.shared.oneKeyLogin()
} }
} else if tabBarName.contains("renewal_plan", caseSensitive: false) {
if YHLoginManager.shared.isLogin() {
surveyViewModel.getRenewalPlanState { state, _ in
if state?.isGeneratePlan == true {
let vc = YHPlanViewController()
UIViewController.current?.navigationController?.pushViewController(vc)
} else {
let vc = YHCustomerInformationQuestionnaireVC()
UIViewController.current?.navigationController?.pushViewController(vc)
}
}
} else {
YHOneKeyLoginManager.shared.oneKeyLogin()
}
} else { } else {
} }
...@@ -163,22 +180,6 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate { ...@@ -163,22 +180,6 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
YHHUD.flash(message: "error:skip_url不能为空") YHHUD.flash(message: "error:skip_url不能为空")
return return
} }
// for test hjl 建明机器IP
// var url = "http://192.168.23.66:10300/superAppBridge.html#/schoolEvaluation"
// for test hjl 梁辉机器IP
// model.skip_url = "http://192.168.23.75:10300/superAppBridge.html#/double11-home"
// for test hjl steve机器IP
// model.skip_url = "http://192.168.52.158:10300/superAppBridge.html#/double11-home"
// for test hjl 测试环境
// model.skip_url = "https://test-hkdiy-h5.galaxy-immi.com/superAppBridge.html#/double11-home"
// for test hjl 贤宇IP
// model.skip_url = "http://192.168.23.35:10300/signatureQrcode/EcqtQYs%2Bxey7t6jLbn6JkQ%3D%3D"
// model.skip_url = "http://192.168.23.71:10300/superAppBridge.html#/double11-home"
// 1.增加app token // 1.增加app token
var url = "" var url = ""
......
...@@ -50,7 +50,7 @@ class YHSurveyMatchResultViewController: YHBaseViewController { ...@@ -50,7 +50,7 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
} }
} }
} }
private lazy var topImageView: UIImageView = { private lazy var topImageView: UIImageView = {
let view = UIImageView() let view = UIImageView()
return view return view
...@@ -83,8 +83,11 @@ class YHSurveyMatchResultViewController: YHBaseViewController { ...@@ -83,8 +83,11 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
button.clipsToBounds = true button.clipsToBounds = true
return button return button
}() }()
var matchAgainEvent: (() -> Void)?
private let pageType: MatchResult private let pageType: MatchResult
init(_ pageType: MatchResult) { init(_ pageType: MatchResult) {
self.pageType = pageType self.pageType = pageType
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
...@@ -93,6 +96,25 @@ class YHSurveyMatchResultViewController: YHBaseViewController { ...@@ -93,6 +96,25 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
@MainActor required init?(coder: NSCoder) { @MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override func backItemClick(_ sender: Any) {
backEvent()
}
/// 是否可以返回,包括点击返回和手势返回,默认YES
override func navigationShouldPop() -> Bool {
backEvent()
return false
}
private func backEvent() {
if pageType == .success {
navigationController?.popToRootViewController(animated: true)
} else {
matchAgainEvent?()
navigationController?.popViewController()
}
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
...@@ -141,7 +163,13 @@ class YHSurveyMatchResultViewController: YHBaseViewController { ...@@ -141,7 +163,13 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
} }
@objc private func matchButtonClicked() { @objc private func matchButtonClicked() {
// if pageType == .success {
let vc = YHPlanViewController()
navigationController?.pushViewController(vc)
} else {
matchAgainEvent?()
navigationController?.popViewController()
}
} }
/// 播放匹配成功 /// 播放匹配成功
......
...@@ -10,6 +10,12 @@ import Lottie ...@@ -10,6 +10,12 @@ import Lottie
import UIKit import UIKit
class YHSurveyMatchingViewController: YHBaseViewController { class YHSurveyMatchingViewController: YHBaseViewController {
private lazy var viewModel = YHSurveyViewModel()
private var timer: Timer?
private var startTime: Date?
private var isRequestCompleted = false
private lazy var lottieView: LottieAnimationView = { private lazy var lottieView: LottieAnimationView = {
let aniView = LottieAnimationView(name: "survey_file_scan") let aniView = LottieAnimationView(name: "survey_file_scan")
aniView.isUserInteractionEnabled = false aniView.isUserInteractionEnabled = false
...@@ -49,7 +55,7 @@ class YHSurveyMatchingViewController: YHBaseViewController { ...@@ -49,7 +55,7 @@ class YHSurveyMatchingViewController: YHBaseViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
setupUI() setupUI()
startAnimation() startLoading()
} }
private func setupUI() { private func setupUI() {
...@@ -86,6 +92,73 @@ class YHSurveyMatchingViewController: YHBaseViewController { ...@@ -86,6 +92,73 @@ class YHSurveyMatchingViewController: YHBaseViewController {
} }
} }
private func startLoading() {
startAnimation()
// 重置状态
progressView.progress = 0
isRequestCompleted = false
startTime = Date()
timer = Timer.scheduledTimer(withTimeInterval: 0.016, repeats: true, block: { [weak self] _ in
guard let self = self else { return }
guard let startTime = self.startTime else { return }
let elapsed = Date().timeIntervalSince(startTime)
let totalDuration: TimeInterval = 4.0 // 总时长4秒
if elapsed < totalDuration {
// 前4秒内,进度条从0%到90%
let progress = Float(elapsed / totalDuration) * 0.9
self.progressView.progress = progress
} else {
// 4秒后
self.timer?.invalidate()
self.timer = nil
if self.isRequestCompleted {
// 如果请求已完成,直接到100%
self.progressView.progress = 1.0
self.loadingCompleted()
} else {
// 如果请求未完成,保持90%,等待请求完成
self.progressView.progress = 0.9
}
}
})
requestState()
}
private func requestState() {
viewModel.getRenewalPlanState { [weak self] _, _ in
guard let self = self else {
return
}
self.isRequestCompleted = true
if self.timer == nil {
// 如果计时器已经结束(超过4秒),直接完成进度条
self.progressView.progress = 1.0
self.loadingCompleted()
}
}
}
private func loadingCompleted() {
stopAnimation()
if let state = viewModel.planState, state.isGeneratePlan {
gotoMatchResultVC(true)
} else {
gotoMatchResultVC(false)
}
}
private func gotoMatchResultVC(_ isSucess: Bool) {
let ctl = YHSurveyMatchResultViewController(isSucess ? .success : .failure)
if !isSucess {
ctl.matchAgainEvent = { [weak self] in
self?.startLoading()
}
}
navigationController?.pushViewController(ctl)
}
private func startAnimation() { private func startAnimation() {
lottieView.play(completion: { _ in lottieView.play(completion: { _ in
// //
......
...@@ -45,6 +45,20 @@ class YHSurveySubmitDoneViewController: YHBaseViewController { ...@@ -45,6 +45,20 @@ class YHSurveySubmitDoneViewController: YHBaseViewController {
button.clipsToBounds = true button.clipsToBounds = true
return button return button
}() }()
override func backItemClick(_ sender: Any) {
backEvent()
}
/// 是否可以返回,包括点击返回和手势返回,默认YES
override func navigationShouldPop() -> Bool {
backEvent()
return false
}
private func backEvent() {
navigationController?.popToRootViewController(animated: true)
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
......
//
// YHSurveyContentModel.swift
// galaxy
//
// Created by alexzzw on 2025/3/28.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
import SmartCodable
// MARK: - YHSurveyContainerModel
class YHSurveyContainerModel: SmartCodable {
var surveyContent: YHSurveyContentModel = YHSurveyContentModel()
// 0老用户1新用户
var type: Int = 0
var defaultAnswers: [YHSurveyDefaultAnswers] = []
var isNewCustomer: Bool {
return type == 1
}
enum CodingKeys: String, CodingKey {
case surveyContent = "survey_content"
case type
case defaultAnswers = "default_answers"
}
required init() {
}
}
// MARK: - YHSurveyDefaultAnswers
class YHSurveyDefaultAnswers: SmartCodable {
var questionId: String = ""
var optionId: [String] = []
enum CodingKeys: String, CodingKey {
case questionId = "question_id"
case optionId = "option_id"
}
required init() {
}
}
// MARK: - YHSurveyContentModel
class YHSurveyContentModel: SmartCodable {
/// 问卷ID
var id: String = ""
/// 问题列表
var questions: [YHSurveyQuestionItem] = []
/// 问卷备注
var remark: String = ""
/// 问卷标题
var title: String = ""
required init() {
}
}
// MARK: - YHSurveyQuestionItem
class YHSurveyQuestionItem: SmartCodable {
/// 业务key,唯一标识一个问券的一个问题
var businessKey: String = ""
/// 问题ID
var id: String = ""
/// 是否必须回答 0:否 1:是
var isRequired: Int = 0
/// 最多允许上传的文件数量 仅对文件上传题有效
var maxFileCount: Int = 0
/// 问题序号
var number: Int = 0
/// repeated article.AnswerItem show_when = 8 [json_name = "show_when"]; //
/// 旧版show_when,即将废弃,请转用show_when_v1 仅当某个或某几个问题答案为XXX时才展示 不同项之间是且关系,选项列表
var options: [YHSurveyQuestionOptionItem] = []
/// 问题备注
var remark: String = ""
var showWhenV1: YHSurveyQuestionItemShowWhenV1 = YHSurveyQuestionItemShowWhenV1()
/// 问题标题
var title: String = ""
/// 问题类型:1:单选 2:多选 3:文本输入 4:文件上传
var type: Int = 0
enum CodingKeys: String, CodingKey {
case id
case number
case options
case remark
case title
case type
case isRequired = "is_required"
case maxFileCount = "max_file_count"
case showWhenV1 = "show_when_v1"
case businessKey = "business_key"
}
required init() {
}
}
// MARK: - YHSurveyQuestionOptionItem
class YHSurveyQuestionOptionItem: SmartCodable {
/// 业务key,唯一标识一个问题的一个选项
var businessKey: String = ""
/// 选项ID
var id: String = ""
/// 跳转的目标问题id,仅当 jump_type=2 时有效
var jumpQuestionId: String = ""
/// 跳转逻辑 0:无需特殊跳转 1:结束问卷 2:跳到某题
var jumpType: Int = 0
/// 选中该选项后是否需要额外填写说明 0:无需 1:选填 2:必填
var needExtra: Int = 0
/// 选项序号
var number: Int = 0
/// 选项备注
var remark: String = ""
/// 该选项对应得分,业务有需要时可用
var score: Int = 0
/// 选项标题
var title: String = ""
enum CodingKeys: String, CodingKey {
case id
case number
case remark
case score
case title
case needExtra = "need_extra"
case jumpType = "jump_type"
case jumpQuestionId = "jump_question_id"
case businessKey = "business_key"
}
required init() {
}
}
// MARK: - YHSurveyQuestionItemShowWhenV1
class YHSurveyQuestionItemShowWhenV1: SmartCodable {
var conditions: [YHSurveyQuestionConditionItem] = []
/// 关系 and/or
var relation: String = ""
var orArray: [YHSurveyQuestionAndOptions] = []
var andArray: [YHSurveyQuestionAndOptions] = []
required init() {
}
func getConitionArray() -> [YHSurveyQuestionAndOptions] {
var questionAndOptions: [YHSurveyQuestionAndOptions] = []
conditions.forEach { conditionItem in
var optionIds: Set<String> = []
let options = conditionItem.options
/// 选项为空,任意选一个即可
if conditionItem.isAnyAnswerAllowed {
let questionAndOption = YHSurveyQuestionAndOptions.init(questionsId: conditionItem.questionId, optionIds: [])
questionAndOptions.append(questionAndOption)
} else {
if options.relation == "and" {
optionIds.formUnion(options.list.compactMap {
$0.optionId
})
let questionAndOption = YHSurveyQuestionAndOptions.init(questionsId: conditionItem.questionId, optionIds: optionIds)
questionAndOptions.append(questionAndOption)
} else if options.relation == "or" {
questionAndOptions.append(contentsOf: options.list.compactMap {
return YHSurveyQuestionAndOptions.init(questionsId: conditionItem.questionId, optionIds: [$0.optionId])
})
}
}
}
return questionAndOptions
}
func didFinishMapping() {
if relation == "or" {
orArray = getConitionArray()
} else if relation == "and" {
andArray = getConitionArray()
}
}
}
// MARK: - YHSurveyQuestionConditionItem
class YHSurveyQuestionConditionItem: SmartCodable {
/// 选中的选项ID与额外说明 仅对单选/多选有效且必需,单选时此项长度为1 兼容旧版 todo 去除
var optionExtra: [YHSurveyConditionOptionExtra] = []
var options: YHSurveyConditionOptions = YHSurveyConditionOptions()
/// 问题ID
var questionId: String = ""
/// 问题类型:1:单选 2:多选 3:文本输入 4:文件上传
var questionType: Int = 0
var isAnyAnswerAllowed: Bool = false
enum CodingKeys: String, CodingKey {
case options
case optionExtra = "option_extra"
case questionId = "question_id"
case questionType = "question_type"
case isAnyAnswerAllowed = "is_any_answer_allowed"
}
required init() {
}
}
// MARK: - YHSurveyConditionOptionExtra
class YHSurveyConditionOptionExtra: SmartCodable {
/// 问题选项额外说明 选中该选项后必需填写额外说明时必需
var extra: String = ""
/// 选项ID 必需
var optionId: String = ""
/// 选项标题 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var title: String = ""
init(extra: String, optionId: String, title: String) {
self.extra = extra
self.optionId = optionId
self.title = title
}
enum CodingKeys: String, CodingKey {
case extra
case title
case optionId = "option_id"
}
required init() {
}
}
// MARK: - YHSurveyConditionOptions
class YHSurveyConditionOptions: SmartCodable {
/// 选项ID与额外说明的列表 单选时此项长度为1
var list: [YHSurveyConditionOptionsItem] = []
/// 关系 and/or
var relation: String = ""
required init() {
}
}
// MARK: - YHSurveyConditionOptionsItem
class YHSurveyConditionOptionsItem: SmartCodable {
var extra: YHSurveyOptionsItemExtra = YHSurveyOptionsItemExtra()
/// 选项ID
var optionId: String = ""
enum CodingKeys: String, CodingKey {
case extra
case optionId = "option_id"
}
required init() {
}
}
// MARK: - YHSurveyOptionsItemExtra
class YHSurveyOptionsItemExtra: SmartCodable {
/// 选项额外说明的内容 仅当 额外说明的判断方式为2时才有效
var content: String = ""
/// 选项额外说明的判断方式 0:无需判断 1:必须非空,不管具体值 2:必须为特定值
var verifyType: Int = 0
enum CodingKeys: String, CodingKey {
case content
case verifyType = "verify_type"
}
required init() {
}
}
struct YHSurveyQuestionAndOptions: SmartCodable, Equatable {
var questionsId: String = ""
var optionIds: Set<String> = []
static func == (lhs: YHSurveyQuestionAndOptions, rhs: YHSurveyQuestionAndOptions) -> Bool {
return lhs.questionsId == rhs.questionsId && lhs.optionIds == rhs.optionIds
}
}
//
// YHSurveyRenewalPlanState.swift
// galaxy
//
// Created by alexzzw on 2025/3/31.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
import SmartCodable
// MARK: - YHSurveyRenewalPlanState
class YHSurveyRenewalPlanState: SmartCodable {
var isGeneratePlan: Bool = false
enum CodingKeys: String, CodingKey {
case isGeneratePlan = "is_generate_plan"
}
required init() {
}
}
//
// YHSurveyResponseModel.swift
// galaxy
//
// Created by alexzzw on 2025/3/31.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
import SmartCodable
// MARK: - YHSurveyResponseModel
class YHSurveyResponseModel: SmartCodable {
var hasHkIdentity: Bool = false
enum CodingKeys: String, CodingKey {
case hasHkIdentity = "has_hk_identity"
}
required init() {
}
}
//
// YHSurveySubmitRequestModel.swift
// galaxy
//
// Created by alexzzw on 2025/3/31.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import Foundation
/// RenewalAdviceSubmitSurveyAnswerRequest 续期建议-提交问卷答案-请求
// MARK: - YHSurveySubmitRequestModel
class YHSurveySubmitRequestModel {
/// 答案详情
var answerDetails: [YHSurveyArticleAnswerItem] = []
/// 问卷id
var surveyId: String = ""
init(answerDetails: [YHSurveyArticleAnswerItem], surveyId: String) {
self.answerDetails = answerDetails
self.surveyId = surveyId
}
}
/// AnswerItem 单个问题答案项
// MARK: - YHSurveyArticleAnswerItem
class YHSurveyArticleAnswerItem {
/// 文件列表 仅对文件上传题有效且必需
var fileList: [YHSurveyAnswerItemFileItem] = []
/// 选中的选项ID与额外说明 仅对单选/多选有效且必需,单选时此项长度为1
var optionExtra: [YHSurveyAnswerItemOptionExtra] = []
/// 问题ID 必需
var questionId: String = ""
/// 问题key 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var questionKey: String = ""
/// 问题类型:1:单选 2:多选 3:文本输入 4:文件上传 必需
var questionType: Int = 0
/// 文本输入内容 仅对文本输入题有效且必需
var text: String = ""
/// 问题标题 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var title: String = ""
init(fileList: [YHSurveyAnswerItemFileItem], optionExtra: [YHSurveyAnswerItemOptionExtra], questionId: String, questionKey: String, questionType: Int, text: String, title: String) {
self.fileList = fileList
self.optionExtra = optionExtra
self.questionId = questionId
self.questionKey = questionKey
self.questionType = questionType
self.text = text
self.title = title
}
}
/// AnswerItemFileItem
// MARK: - YHSurveyAnswerItemFileItem
class YHSurveyAnswerItemFileItem {
/// 文件名称 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var name: String = ""
/// 文件大小 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var size: Int = 0
/// 文件类型 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var type: String = ""
/// 上传时间(格式:YYYY-MM-DD HH:mm:ss) 可选 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var uploadAt: String = ""
/// 文件url 必需
var url: String = ""
init(name: String, size: Int, type: String, uploadAt: String, url: String) {
self.name = name
self.size = size
self.type = type
self.uploadAt = uploadAt
self.url = url
}
}
/// AnswerItemOptionExtra
// MARK: - YHSurveyAnswerItemOptionExtra
class YHSurveyAnswerItemOptionExtra {
/// 问题选项额外说明 选中该选项后必需填写额外说明时必需
var extra: String = ""
/// 选项ID 必需
var optionId: String = ""
/// 选项key 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var optionKey: String = ""
/// 选项标题 可选 提交答案时,建议设置该字段,会作为提交记录留底;show_when场景下,忽略该字段
var title: String = ""
init(extra: String, optionId: String, optionKey: String, title: String) {
self.extra = extra
self.optionId = optionId
self.optionKey = optionKey
self.title = title
}
}
...@@ -7,33 +7,32 @@ ...@@ -7,33 +7,32 @@
// //
import UIKit import UIKit
import AttributedString
class YHMakePlanBottomView: UIView { class YHMakePlanBottomView: UIView {
// MARK: - UI Elements // MARK: - UI Elements
private lazy var priceLabel: UILabel = { private lazy var priceLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = UIFont.systemFont(ofSize: 24, weight: .bold) let a: ASAttributedString = .init("¥", .font(UIFont.PFSC_M(ofSize: 20)), .foreground(UIColor.mainTextColor))
label.textColor = .black let b: ASAttributedString = .init("58999.00", .font(UIFont.PFSC_M(ofSize: 28)), .foreground(UIColor.mainTextColor))
label.textAlignment = .left label.attributed.text = a + b
return label return label
}() }()
private lazy var priceButton: UIButton = { private lazy var priceButton: UIButton = {
let label = UIButton() let label = UIButton()
label.setTitle(">", for: .normal) label.setImage(UIImage(named: "make_plan_up"), for: .normal)
label.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
label.setTitleColor(UIColor.systemBlue, for: .normal)
label.addTarget(self, action: #selector(handleAction), for: .touchUpInside) label.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
return label return label
}() }()
private lazy var actionButton: UIButton = { private lazy var actionButton: YHImageTextButton = {
let button = UIButton(type: .system) let button = YHImageTextButton(title: "去办理", image: UIImage(named: "make_plan_next"))
button.setTitle("去办理 →", for: .normal) button.setTitleColor(UIColor(hex: 0xffffff), for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium) button.titleLabel?.font = UIFont.PFSC_M(ofSize: 16)
button.setTitleColor(UIColor.systemBlue, for: .normal) button.layer.cornerRadius = 2
button.addTarget(self, action: #selector(handleAction), for: .touchUpInside) button.backgroundColor = UIColor.mainTextColor
return button return button
}() }()
...@@ -41,7 +40,9 @@ class YHMakePlanBottomView: UIView { ...@@ -41,7 +40,9 @@ class YHMakePlanBottomView: UIView {
var price: String = "" { var price: String = "" {
didSet { didSet {
priceLabel.text = "\(price)" let a: ASAttributedString = .init("¥", .font(UIFont.PFSC_M(ofSize: 20)), .foreground(UIColor.mainTextColor))
let b: ASAttributedString = .init("\(price)", .font(UIFont.PFSC_M(ofSize: 28)), .foreground(UIColor.mainTextColor))
priceLabel.attributed.text = a + b
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
// //
import UIKit import UIKit
import AttributedString
class YHMakePlanCardView: UIView { class YHMakePlanCardView: UIView {
...@@ -20,16 +21,16 @@ class YHMakePlanCardView: UIView { ...@@ -20,16 +21,16 @@ class YHMakePlanCardView: UIView {
private lazy var titleLabel: UILabel = { private lazy var titleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = UIFont.systemFont(ofSize: 16, weight: .semibold) label.font = UIFont.PFSC_M(ofSize: 16)
label.textColor = .darkText label.textColor = .mainTextColor
label.numberOfLines = 1 label.numberOfLines = 1
return label return label
}() }()
private lazy var subtitleLabel: UILabel = { private lazy var subtitleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.font = UIFont.systemFont(ofSize: 13, weight: .regular) label.font = UIFont.PFSC_R(ofSize: 12)
label.textColor = .gray label.textColor = UIColor(hex: 0x8993a2)
label.numberOfLines = 2 label.numberOfLines = 2
return label return label
}() }()
...@@ -40,25 +41,27 @@ class YHMakePlanCardView: UIView { ...@@ -40,25 +41,27 @@ class YHMakePlanCardView: UIView {
return view return view
}() }()
private lazy var storeButton: UIButton = { private lazy var storeButton: YHImageTextButton = {
let button = UIButton() let button = YHImageTextButton(title: "星企航(7年)", image: UIImage(named: "make_plan_down"))
button.setTitle("星企航(7年)", for: .normal) button.layer.cornerRadius = 2
button.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium) button.backgroundColor = UIColor(hex: 0xf5f6f8)
button.setTitleColor(UIColor.systemBlue, for: .normal)
// button.addTarget(self, action: #selector(handleAction), for: .touchUpInside) // button.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
return button return button
}() }()
private lazy var priceTagView: UILabel = { private lazy var priceTagView: UILabel = {
let label = UILabel() let label = UILabel()
label.font = UIFont.systemFont(ofSize: 14, weight: .medium) let a: ASAttributedString = .init("¥", .font(UIFont.PFSC_M(ofSize: 14)), .foreground(UIColor.mainTextColor))
label.textColor = UIColor(red: 0.2, green: 0.4, blue: 0.8, alpha: 1.0) let b: ASAttributedString = .init("58999.00", .font(UIFont.PFSC_M(ofSize: 20)), .foreground(UIColor.mainTextColor))
label.attributed.text = a + b
return label return label
}() }()
private lazy var selectButton: UIButton = { private lazy var selectButton: UIButton = {
let button = UIButton() let button = UIButton()
button.backgroundColor = .red button.setImage(UIImage(named: "make_plan_select"), for: .selected)
button.setImage(UIImage(named: "make_plan_normal"), for: .normal)
// button.addTarget(self, action: #selector(handleAction), for: .touchUpInside) // button.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
return button return button
}() }()
...@@ -110,13 +113,14 @@ class YHMakePlanCardView: UIView { ...@@ -110,13 +113,14 @@ class YHMakePlanCardView: UIView {
make.height.width.equalTo(86) make.height.width.equalTo(86)
} }
storeButton.translatesAutoresizingMaskIntoConstraints = false
storeButton.snp.makeConstraints { make in storeButton.snp.makeConstraints { make in
make.top.equalToSuperview().offset(60) make.top.equalToSuperview().offset(60)
make.left.equalToSuperview().offset(110) make.left.equalToSuperview().offset(110)
make.width.equalTo(97) // make.width.equalTo(97)
make.height.equalTo(22) make.height.equalTo(22)
} }
priceTagView.snp.makeConstraints { make in priceTagView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(86) make.top.equalToSuperview().offset(86)
make.left.equalToSuperview().offset(110) make.left.equalToSuperview().offset(110)
...@@ -127,6 +131,7 @@ class YHMakePlanCardView: UIView { ...@@ -127,6 +131,7 @@ class YHMakePlanCardView: UIView {
make.right.bottom.equalTo(-18) make.right.bottom.equalTo(-18)
make.height.width.equalTo(16) make.height.width.equalTo(16)
} }
} }
// MARK: - Configuration // MARK: - Configuration
...@@ -135,6 +140,7 @@ class YHMakePlanCardView: UIView { ...@@ -135,6 +140,7 @@ class YHMakePlanCardView: UIView {
titleLabel.text = data.title titleLabel.text = data.title
subtitleLabel.text = data.subtitle subtitleLabel.text = data.subtitle
priceTagView.text = data.price priceTagView.text = data.price
storeButton.updateContent()
} }
} }
...@@ -146,3 +152,76 @@ struct CompanyPackageData { ...@@ -146,3 +152,76 @@ struct CompanyPackageData {
let price: String let price: String
let showCheckmark: Bool let showCheckmark: Bool
} }
class YHImageTextButton: UIButton {
var spacing: CGFloat = 4 // 文字和图片之间的间距
var horizontalPadding: CGFloat = 8 // 左右边距
init(title: String, image: UIImage?) {
super.init(frame: .zero)
// 基础配置
setTitle(title, for: .normal)
setImage(image, for: .normal)
setTitleColor(UIColor(hex: 0x6a7586), for: .normal)
titleLabel?.font = UIFont.PFSC_R(ofSize: 12)
// 关键配置:图片在右侧
semanticContentAttribute = .forceRightToLeft
contentHorizontalAlignment = .center
// 禁用系统默认的inset调整
adjustsImageWhenHighlighted = false
imageView?.translatesAutoresizingMaskIntoConstraints = false
titleLabel?.translatesAutoresizingMaskIntoConstraints = false
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// 关键:正确计算固有内容大小
override var intrinsicContentSize: CGSize {
let titleSize = titleLabel?.intrinsicContentSize ?? .zero
let imageSize = imageView?.intrinsicContentSize ?? .zero
// 总宽度 = 文字宽度 + 图片宽度 + 间距 + 左右边距×2
let totalWidth = titleSize.width + imageSize.width + spacing + 2 * horizontalPadding
let maxHeight = max(titleSize.height, imageSize.height)
return CGSize(width: totalWidth, height: maxHeight)
}
// 关键:手动布局子视图
override func layoutSubviews() {
super.layoutSubviews()
guard let titleLabel = titleLabel, let imageView = imageView else { return }
// 手动计算布局
let totalContentWidth = titleLabel.intrinsicContentSize.width + spacing + imageView.intrinsicContentSize.width
let startX = (bounds.width - totalContentWidth) / 2
// 定位文字和图片
titleLabel.frame = CGRect(
x: startX,
y: (bounds.height - titleLabel.intrinsicContentSize.height) / 2,
width: titleLabel.intrinsicContentSize.width,
height: titleLabel.intrinsicContentSize.height
)
imageView.frame = CGRect(
x: titleLabel.frame.maxX + spacing,
y: (bounds.height - imageView.intrinsicContentSize.height) / 2,
width: imageView.intrinsicContentSize.width,
height: imageView.intrinsicContentSize.height
)
}
// 在文本或图片变化时调用
func updateContent() {
invalidateIntrinsicContentSize()
setNeedsLayout()
}
}
...@@ -25,7 +25,7 @@ class YHMakePlanCusttomHeadView: UIView { ...@@ -25,7 +25,7 @@ class YHMakePlanCusttomHeadView: UIView {
private let underlineView: UIView = { private let underlineView: UIView = {
let view = UIView() let view = UIView()
view.backgroundColor = .systemBlue view.backgroundColor = UIColor.mainTextColor
return view return view
}() }()
...@@ -51,7 +51,7 @@ class YHMakePlanCusttomHeadView: UIView { ...@@ -51,7 +51,7 @@ class YHMakePlanCusttomHeadView: UIView {
let button = UIButton(type: .system) let button = UIButton(type: .system)
button.setTitle(title, for: .normal) button.setTitle(title, for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 14) button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
button.setTitleColor(index == 0 ? .systemBlue : .gray, for: .normal) button.setTitleColor(index == 0 ? UIColor.mainTextColor: UIColor(hex: 0x6a7586), for: .normal)
button.tag = index button.tag = index
button.addTarget(self, action: #selector(tabTapped(_:)), for: .touchUpInside) button.addTarget(self, action: #selector(tabTapped(_:)), for: .touchUpInside)
buttons.append(button) buttons.append(button)
...@@ -72,8 +72,8 @@ class YHMakePlanCusttomHeadView: UIView { ...@@ -72,8 +72,8 @@ class YHMakePlanCusttomHeadView: UIView {
underlineView.snp.makeConstraints { make in underlineView.snp.makeConstraints { make in
make.top.equalTo(stackView.snp.bottom) make.top.equalTo(stackView.snp.bottom)
make.height.equalTo(2) make.height.equalTo(2)
make.width.equalToSuperview().dividedBy(tabs.count) make.width.equalTo(16)
make.leading.equalToSuperview() make.centerX.equalTo(buttons[0].snp.centerX)
} }
} }
...@@ -83,13 +83,16 @@ class YHMakePlanCusttomHeadView: UIView { ...@@ -83,13 +83,16 @@ class YHMakePlanCusttomHeadView: UIView {
guard newIndex != selectedIndex else { return } guard newIndex != selectedIndex else { return }
// Update colors // Update colors
buttons[selectedIndex].setTitleColor(.gray, for: .normal) buttons[selectedIndex].setTitleColor(UIColor(hex: 0x6a7586), for: .normal)
buttons[newIndex].setTitleColor(.systemBlue, for: .normal) buttons[newIndex].setTitleColor(UIColor.mainTextColor, for: .normal)
// Animate underline // Animate underline
UIView.animate(withDuration: 0.3) { UIView.animate(withDuration: 0.3) {
self.underlineView.snp.updateConstraints { make in self.underlineView.snp.remakeConstraints { make in
make.leading.equalToSuperview().offset(sender.frame.origin.x) make.top.equalTo(self.stackView.snp.bottom)
make.height.equalTo(2)
make.width.equalTo(16)
make.centerX.equalTo(self.buttons[newIndex].snp.centerX)
} }
self.layoutIfNeeded() self.layoutIfNeeded()
} }
......
...@@ -52,7 +52,10 @@ class YHMakePlanShareAlertView: UIView { ...@@ -52,7 +52,10 @@ class YHMakePlanShareAlertView: UIView {
sureButton = { sureButton = {
let button = UIButton(type: .custom) let button = UIButton(type: .custom)
button.backgroundColor = .black button.backgroundColor = UIColor(hex: 0xf5f6f8)
button.setTitleColor(.mainTextColor, for: .normal)
button.setTitle("取消", for: .normal)
button.layer.cornerRadius = 4
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside) button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
return button return button
}() }()
...@@ -80,7 +83,7 @@ class YHMakePlanShareAlertView: UIView { ...@@ -80,7 +83,7 @@ class YHMakePlanShareAlertView: UIView {
rightButton = { rightButton = {
let button = YHShareButton() let button = YHShareButton()
button.setContent("invitation_with_gifts_share_center", "复制链接") button.setContent("invitation_with_gifts_share_link", "复制链接")
button.addTarget(self, action: #selector(wxClick), for: .touchUpInside) button.addTarget(self, action: #selector(wxClick), for: .touchUpInside)
return button return button
}() }()
......
...@@ -14,8 +14,8 @@ class YHMakePlanStateHeadView: UIView { ...@@ -14,8 +14,8 @@ class YHMakePlanStateHeadView: UIView {
private let yearsLabel: UILabel = { private let yearsLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = "5" label.text = "5"
label.font = .boldSystemFont(ofSize: 32) label.font = UIFont.PFSC_M(ofSize: 32)
label.textColor = .label label.textColor = .mainTextColor
label.textAlignment = .center label.textAlignment = .center
return label return label
}() }()
...@@ -23,8 +23,8 @@ class YHMakePlanStateHeadView: UIView { ...@@ -23,8 +23,8 @@ class YHMakePlanStateHeadView: UIView {
private let yearsDescriptionLabel: UILabel = { private let yearsDescriptionLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = "预计可续期(年)" label.text = "预计可续期(年)"
label.font = .systemFont(ofSize: 14) label.font = UIFont.PFSC_M(ofSize: 14)
label.textColor = .secondaryLabel label.textColor = UIColor(hex: 0x8893a2)
label.textAlignment = .center label.textAlignment = .center
return label return label
}() }()
...@@ -32,8 +32,8 @@ class YHMakePlanStateHeadView: UIView { ...@@ -32,8 +32,8 @@ class YHMakePlanStateHeadView: UIView {
private let percentageLabel: UILabel = { private let percentageLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = "90%" label.text = "90%"
label.font = .boldSystemFont(ofSize: 32) label.font = UIFont.PFSC_M(ofSize: 32)
label.textColor = .label label.textColor = .mainTextColor
label.textAlignment = .center label.textAlignment = .center
return label return label
}() }()
...@@ -41,8 +41,8 @@ class YHMakePlanStateHeadView: UIView { ...@@ -41,8 +41,8 @@ class YHMakePlanStateHeadView: UIView {
private let progressDescriptionLabel: UILabel = { private let progressDescriptionLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = "续签综合通过率" label.text = "续签综合通过率"
label.font = .systemFont(ofSize: 14) label.font = UIFont.PFSC_M(ofSize: 14)
label.textColor = .secondaryLabel label.textColor = UIColor(hex: 0x8893a2)
label.textAlignment = .center label.textAlignment = .center
return label return label
}() }()
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved. // Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
// //
import AttributedString
import UIKit import UIKit
class YHSurveyTableViewCell: YHResignDocumentCell { class YHSurveyTableViewCell: YHResignDocumentCell {
...@@ -75,8 +76,14 @@ class YHSurveyTableViewCell: YHResignDocumentCell { ...@@ -75,8 +76,14 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
// MARK: - Configuration // MARK: - Configuration
func configure(with question: String, options: [String], selectedIndex: Int? = nil, type: QuestionType = .singleChoice) { func configure(with question: String, isRequired: Bool = true, options: [String], selectedIndices: [Int], type: QuestionType = .singleChoice) {
questionLabel.text = question let questionAttr: ASAttributedString = .init("\(question)", .font(UIFont.PFSC_M(ofSize: 15)), .foreground(UIColor.mainTextColor))
if isRequired {
let starAttr: ASAttributedString = .init("*", .font(UIFont.PFSC_M(ofSize: 15)), .foreground(UIColor.failColor))
questionLabel.attributed.text = starAttr + questionAttr
} else {
questionLabel.attributed.text = questionAttr
}
questionType = type questionType = type
// Clear previous options // Clear previous options
...@@ -84,45 +91,72 @@ class YHSurveyTableViewCell: YHResignDocumentCell { ...@@ -84,45 +91,72 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
// Add new options // Add new options
for (index, option) in options.enumerated() { for (index, option) in options.enumerated() {
let optionView = createOptionView(text: option, isSelected: index == selectedIndex, index: index) let optionView = createOptionView(text: option, isSelected: selectedIndices.contains(index), index: index)
optionsStackView.addArrangedSubview(optionView) optionsStackView.addArrangedSubview(optionView)
} }
} }
private func createOptionView(text: String, isSelected: Bool, index: Int) -> UIView { private func createOptionView(text: String, isSelected: Bool, index: Int) -> UIView {
let container = UIControl() let item = YHSurveyQuestionItemView()
container.tag = index item.tag = index
container.addTarget(self, action: #selector(optionButtonTapped(_:)), for: .touchUpInside) item.addTarget(self, action: #selector(optionButtonTapped(_:)), for: .touchUpInside)
item.setup(text: text, isSelected: isSelected)
return item
}
// MARK: - Actions
@objc private func optionButtonTapped(_ sender: UIControl) {
optionsStackView.arrangedSubviews.enumerated().forEach { index, subView in
guard let item = subView as? YHSurveyQuestionItemView else {
return
}
item.updateState(isSelected: sender.tag == index)
}
optionSelected?(sender.tag)
}
}
class YHSurveyQuestionItemView: UIControl {
private lazy var iconView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private lazy var contentLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.text = text
label.textColor = .mainTextColor label.textColor = .mainTextColor
label.font = .PFSC_R(ofSize: 14) label.font = .PFSC_R(ofSize: 14)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(iconView)
addSubview(contentLabel)
let icon = UIImageView() iconView.snp.makeConstraints { make in
icon.image = isSelected ? UIImage(named: "plan_question_checked") : UIImage(named: "plan_question_unchecked")
// icon.image = isSelected ? UIImage(systemName: questionType == .singleChoice ? "largecircle.fill.circle" : "checkmark.square.fill") :
// UIImage(systemName: questionType == .singleChoice ? "circle" : "square")
// icon.tintColor = isSelected ? .systemBlue : .lightGray
container.addSubview(icon)
container.addSubview(label)
icon.snp.makeConstraints { make in
make.left.centerY.equalToSuperview() make.left.centerY.equalToSuperview()
make.width.height.equalTo(14) make.width.height.equalTo(14)
} }
label.snp.makeConstraints { make in contentLabel.snp.makeConstraints { make in
make.left.equalTo(icon.snp.right).offset(8) make.left.equalTo(iconView.snp.right).offset(8)
make.right.top.bottom.equalToSuperview() make.right.top.bottom.equalToSuperview()
} }
return container
} }
// MARK: - Actions required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@objc private func optionButtonTapped(_ sender: UIControl) { }
optionSelected?(sender.tag)
func setup(text: String, isSelected: Bool) {
updateState(isSelected: isSelected)
contentLabel.text = text
}
func updateState(isSelected: Bool) {
iconView.image = isSelected ? UIImage(named: "plan_question_checked") : UIImage(named: "plan_question_unchecked")
} }
} }
//
// YHSurveyViewModel.swift
// galaxy
//
// Created by alexzzw on 2025/3/28.
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import UIKit
class YHSurveyViewModel: YHBaseViewModel {
var surveyContainerModel: YHSurveyContainerModel?
var responseModel: YHSurveyResponseModel?
var planState: YHSurveyRenewalPlanState?
}
extension YHSurveyViewModel {
/*
问卷内容
*/
func getSurveyContent(callback: @escaping (_ contentModel: YHSurveyContainerModel?, _ error: YHErrorModel?) -> Void) {
let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.Survey.surveyContent
_ = YHNetRequest.getRequest(url: strUrl, params: [:]) { [weak self] json, _ in
// 1. json字符串 转 对象
printLog("model 是 ==> \(json)")
if json.code == 200 {
guard let dic = json.data?.peel as? [String: Any], let resultModel = YHSurveyContainerModel.deserialize(from: dic) else {
let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
callback(nil, err)
return
}
self?.surveyContainerModel = resultModel
callback(resultModel, nil)
} else {
let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
callback(nil, err)
}
} failBlock: { err in
callback(nil, err)
}
}
/*
问卷提交
*/
func submitSurveyAnswer(requestModel: YHSurveySubmitRequestModel, callBackBlock: @escaping (_ responseModel: YHSurveyResponseModel?, _ error: YHErrorModel?) -> Void) {
let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.Survey.submitSurveyAnswer
let answerDetails: [[String: Any]] = requestModel.answerDetails.compactMap({ item in
let optionExtra: [[String: Any]] = item.optionExtra.compactMap { extra in
["option_id": extra.optionId, "extra": extra.extra, "title": extra.title, "option_key": extra.optionKey]
}
return ["question_id": item.questionId, "question_type": item.questionType, "text": "", "title": item.title, "question_key": item.questionKey, "option_extra": optionExtra, "file_list": []]
})
let params: [String: Any] = ["survey_id": requestModel.surveyId, "answer_details": answerDetails]
_ = YHNetRequest.postRequest(url: strUrl, params: params) { [weak self] json, _ in
// 1. json字符串 转 对象
if json.code == 200 {
guard let dic = json.data?.peel as? [String: Any], let resultModel = YHSurveyResponseModel.deserialize(from: dic) else {
let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
callBackBlock(nil, err)
return
}
self?.responseModel = resultModel
callBackBlock(resultModel, nil)
} else {
let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
callBackBlock(nil, err)
}
} failBlock: { err in
callBackBlock(nil, err)
}
}
/*
问卷是否生成方案
*/
func getRenewalPlanState(callback: @escaping (_ planState: YHSurveyRenewalPlanState?, _ error: YHErrorModel?) -> Void) {
let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.Survey.getRenewalPlanState
_ = YHNetRequest.getRequest(url: strUrl, params: [:]) { [weak self] json, _ in
// 1. json字符串 转 对象
printLog("model 是 ==> \(json)")
if json.code == 200 {
guard let dic = json.data?.peel as? [String: Any], let resultModel = YHSurveyRenewalPlanState.deserialize(from: dic) else {
let err = YHErrorModel(errorCode: YHErrorCode.dictParseError.rawValue, errorMsg: YHErrorCode.dictParseError.description())
callback(nil, err)
return
}
self?.planState = resultModel
callback(resultModel, nil)
} else {
let err = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg.isEmpty ? "" : json.msg)
callback(nil, err)
}
} failBlock: { err in
callback(nil, err)
}
}
}
...@@ -755,7 +755,13 @@ class YHAllApiName { ...@@ -755,7 +755,13 @@ class YHAllApiName {
// 续签方案 // 续签方案
struct ResignPlan { struct ResignPlan {
static let planlistApi = "super-app/renewal/advice/get-renewal-plan" static let planlistApi = "super-app/renewal/advice/get-renewal-plan"
}
// 问卷
struct Survey {
static let surveyContent = "super-app/renewal/advice/survey-content"
static let submitSurveyAnswer = "super-app/renewal/advice/submit-survey-answer"
static let getRenewalPlanState = "super-app/renewal/advice/get-renewal-plan-is-generate"
} }
} }
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "invitation_with_gifts_share_link@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "invitation_with_gifts_share_link@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "make_plan_down@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "make_plan_down@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "make_plan_next@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "make_plan_next@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "make_plan_normal@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "make_plan_normal@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "make_plan_select@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "make_plan_select@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "make_plan_up@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "make_plan_up@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment