Commit 689a2b5b authored by pete谢兆麟's avatar pete谢兆麟
parents 361d97f8 2face72e
......@@ -1178,6 +1178,11 @@
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 */; };
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 */; };
04AE20102D12CFAF00891D24 /* YHGCApplicationTypeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFD2D12CFAF00891D24 /* YHGCApplicationTypeController.swift */; };
04AE20112D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04AE1FFE2D12CFAF00891D24 /* YHGCApplicationTypeResultController.swift */; };
......@@ -2476,6 +2481,11 @@
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>"; };
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>"; };
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>"; };
......@@ -6800,7 +6810,11 @@
isa = PBXGroup;
children = (
04D8FF582D925E6700703C75 /* YHPlanModel.swift */,
04A750EE2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift */,
04A750D32D93DFED00974E5F /* YHSurveyQuestionType.swift */,
04A750EC2D963BE900974E5F /* YHSurveyContentModel.swift */,
04A750F02D9AAD0300974E5F /* YHSurveyResponseModel.swift */,
04A750F22D9AB95300974E5F /* YHSurveyRenewalPlanState.swift */,
);
path = M;
sourceTree = "<group>";
......@@ -6809,6 +6823,7 @@
isa = PBXGroup;
children = (
04D8FF5A2D925E8100703C75 /* YHPlanViewModel.swift */,
04A750EA2D963AFE00974E5F /* YHSurveyViewModel.swift */,
);
path = VM;
sourceTree = "<group>";
......@@ -7161,6 +7176,7 @@
045C0FBF2D12CA5F00BD2DC0 /* YHMyLikeViewController.swift in Sources */,
045C0FC02D12CA5F00BD2DC0 /* YHHomeCollectionLayout.swift in Sources */,
045C0FC12D12CA5F00BD2DC0 /* YHOffivialApprovalGuildLineCheckView.swift in Sources */,
04A750ED2D963BE900974E5F /* YHSurveyContentModel.swift in Sources */,
045C0FC22D12CA5F00BD2DC0 /* YHIncomeTypesCell.swift in Sources */,
045C0FC32D12CA5F00BD2DC0 /* YHIncomeRecordSummaryCell.swift in Sources */,
045C0FC42D12CA5F00BD2DC0 /* YHSheetPickerViewType.swift in Sources */,
......@@ -7676,6 +7692,7 @@
045C11752D12CA5F00BD2DC0 /* YHAIProductCell.swift in Sources */,
045C11762D12CA5F00BD2DC0 /* YHHKRecordsHeaderCell.swift in Sources */,
045C11772D12CA5F00BD2DC0 /* YHWorkMessageSelectTableViewCell.swift in Sources */,
04A750F32D9AB95300974E5F /* YHSurveyRenewalPlanState.swift in Sources */,
045C11782D12CA5F00BD2DC0 /* YHResignGuidelinesViewModel.swift in Sources */,
045C11792D12CA5F00BD2DC0 /* YHFormItemDoubleChoiceCell.swift in Sources */,
045C117A2D12CA5F00BD2DC0 /* YHEmailInputAlertView.swift in Sources */,
......@@ -7764,6 +7781,7 @@
045C11C62D12CA5F00BD2DC0 /* YHListViewController.swift in Sources */,
045C11C72D12CA5F00BD2DC0 /* YHWorkExperiencePositionTableViewCell.swift in Sources */,
045C11C82D12CA5F00BD2DC0 /* YHOrderSearchViewController.swift in Sources */,
04A750EF2D9A9E8A00974E5F /* YHSurveySubmitRequestModel.swift in Sources */,
045C11C92D12CA5F00BD2DC0 /* YHNoDataTipsView.swift in Sources */,
045C11CA2D12CA5F00BD2DC0 /* YHHKRecordsInfoItemCell.swift in Sources */,
04D8FF792D97BDBD00703C75 /* YHPlanShareViewController.swift in Sources */,
......@@ -8048,6 +8066,7 @@
045C12B22D12CA5F00BD2DC0 /* YHResignUploadDetailViewModel.swift in Sources */,
045C12B32D12CA5F00BD2DC0 /* YHFamilyInfoConfirmViewModel.swift in Sources */,
045C12B42D12CA5F00BD2DC0 /* YHLifeDetailViewController.swift in Sources */,
04A750F12D9AAD0300974E5F /* YHSurveyResponseModel.swift in Sources */,
045C12B52D12CA5F00BD2DC0 /* YHIncomeRecordWorkExperienceViewController.swift in Sources */,
045C12B62D12CA5F00BD2DC0 /* YHMyLikeViewModel.swift in Sources */,
045C12B72D12CA5F00BD2DC0 /* YHCertificateUploadSheetView.swift in Sources */,
......@@ -8129,6 +8148,7 @@
045C12F92D12CA5F00BD2DC0 /* YHEducationCertificateConfirmCell.swift in Sources */,
045C12FA2D12CA5F00BD2DC0 /* YHAcademicPreviewModel.swift in Sources */,
045C12FB2D12CA5F00BD2DC0 /* YHHomeIdentityViewController.swift in Sources */,
04A750EB2D963AFE00974E5F /* YHSurveyViewModel.swift in Sources */,
045C12FC2D12CA5F00BD2DC0 /* YHAdopterAddModel.swift in Sources */,
045C12FD2D12CA5F00BD2DC0 /* YHOtherLoginViewController.swift in Sources */,
045C12FE2D12CA5F00BD2DC0 /* YHInformationAuthorizationStepTwoViewController.swift in Sources */,
......
......@@ -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) {
super.init(frame: frame)
......@@ -113,6 +114,22 @@ private extension YHHomeBannerView {
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 {
}
......@@ -163,22 +180,6 @@ extension YHHomeBannerView: FSPagerViewDataSource, FSPagerViewDelegate {
YHHUD.flash(message: "error:skip_url不能为空")
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
var url = ""
......
......@@ -11,13 +11,15 @@ import JXSegmentedView
class YHPlanViewController: YHBaseViewController {
let viewModel = YHPlanViewModel()
var infoArr: [String] = ["", "", "", "", "", ""]
var cases: [String] = ["水电费噶事多发结石冷风机拉萨反垃圾算法逻辑的山卡拉飞机啊索拉卡飞机啊拉卡萨",
"阿斯顿发发", "阿斯顿发生大法师懂法守法说法大萨达法司法发沙发是打发三大发实达防擦是打发",
"啊所发生的发生的放假啦苏卡达飞机拉萨开发机阿萨拉法基阿萨拉开发",
"双法防",
"沙发上",
"啊防守打法"]
var analyzeArr: [YHPlanAnalyzeModel] = [YHPlanAnalyzeModel(),
YHPlanAnalyzeModel(),
YHPlanAnalyzeModel(),
YHPlanAnalyzeModel()]
var policyArr: [YHPlanCaseModel] = []
var caseArr: [YHPlanCaseModel] = []
let headerViewHeight = 146.0
let topScrollHeight = 146.0-44.0
......@@ -247,7 +249,6 @@ class YHPlanViewController: YHBaseViewController {
lazy var policyVieiw: YHPlanPolicyCarouselView = {
let v = YHPlanPolicyCarouselView(frame: CGRect(x: 0, y: 0, width: KScreenWidth, height: 268))
v.bannerArr = ["", "", "", ""]
return v
}()
......@@ -305,6 +306,53 @@ class YHPlanViewController: YHBaseViewController {
make.top.equalTo(10+k_Height_statusBar())
make.width.height.equalTo(24)
}
requestData()
}
func requestData() {
viewModel.requetResignPlanInfo {
[weak self] _, _ in
guard let self = self else { return }
var workModel = YHPlanAnalyzeModel()
workModel.name = "work"
var liveModel = YHPlanAnalyzeModel()
liveModel.name = "live"
var investModel = YHPlanAnalyzeModel()
investModel.name = "invest"
var stayModel = YHPlanAnalyzeModel()
stayModel.name = "stay"
for item in self.viewModel.planListModel.list {
if item.name == "work" {
workModel = item
} else if item.name == "live" {
liveModel = item
} else if item.name == "invest" {
investModel = item
} else if item.name == "stay" {
stayModel = item
}
}
workModel.score = self.viewModel.planListModel.basic.work_score
liveModel.score = self.viewModel.planListModel.basic.live_score
investModel.score = self.viewModel.planListModel.basic.invest_score
stayModel.score = self.viewModel.planListModel.basic.stay_time_score
analyzeArr.removeAll()
analyzeArr.append(contentsOf: [workModel, liveModel, investModel, stayModel])
policyVieiw.bannerArr = policyArr
caseArr.removeAll()
caseArr.append(contentsOf: self.viewModel.planListModel.plan_article_case)
self.tableView.reloadData()
}
}
}
......@@ -325,30 +373,39 @@ extension YHPlanViewController: UITableViewDelegate, UITableViewDataSource {
guard let cell1 = tableView.dequeueReusableCell(withIdentifier: YHPlanScoreCell.cellReuseIdentifier, for: indexPath) as? YHPlanScoreCell else {
return UITableViewCell()
}
cell1.model = self.viewModel.planListModel.basic
return cell1
} else if indexPath.section < 5 {
guard let cell2 = tableView.dequeueReusableCell(withIdentifier: YHPlanAnalyzeInfoCell.cellReuseIdentifier, for: indexPath) as? YHPlanAnalyzeInfoCell else {
return UITableViewCell()
}
cell2.products = ["", ""]
cell2.model = analyzeArr[indexPath.section-1]
return cell2
} else if indexPath.section == 5 {
guard let cell3 = tableView.dequeueReusableCell(withIdentifier: YHPlanCustomerCaseListCell.cellReuseIdentifier, for: indexPath) as? YHPlanCustomerCaseListCell else {
return UITableViewCell()
if caseArr.count > 0 {
guard let cell3 = tableView.dequeueReusableCell(withIdentifier: YHPlanCustomerCaseListCell.cellReuseIdentifier, for: indexPath) as? YHPlanCustomerCaseListCell else {
return UITableViewCell()
}
cell3.cases = self.caseArr
return cell3
}
cell3.cases = self.cases
return cell3
}
}
let defaultCell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
defaultCell.backgroundColor = .clear
defaultCell.contentView.backgroundColor = .clear
return defaultCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 5 {
return getCaseListHeight()
if caseArr.count > 0 {
return getCaseListHeight()
}
return 1.0
}
return UITableView.automaticDimension
}
......@@ -360,14 +417,19 @@ extension YHPlanViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
if section == 4 {
return 268.0
if policyArr.count > 0 {
return 268.0
}
return 1.0
}
return 1.0
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
if section == 4 {
return self.policyVieiw
if policyArr.count > 0 {
return self.policyVieiw
}
}
let view = UIView()
return view
......@@ -391,8 +453,8 @@ extension YHPlanViewController: UITableViewDelegate, UITableViewDataSource {
var yOffset1 = 0.0
var yOffset2 = 0.0
for (index, _) in cases.enumerated() {
let textHeight = self.getHeigt(font: UIFont.PFSC_R(ofSize: 14), width: cellWidth-8.0*2.0, string: cases[index])
for (index, item) in caseArr.enumerated() {
let textHeight = self.getHeigt(font: UIFont.PFSC_R(ofSize: 14), width: cellWidth-8.0*2.0, string: item.title)
let caseCellHeight = textHeight + (cellWidth*(200.0/166.0) + 8.0+12.0+10.0)
if index % 2 == 0 {
......@@ -435,7 +497,6 @@ extension YHPlanViewController: UIScrollViewDelegate {
tableView.setContentOffset(CGPoint(x: 0, y: headerViewHeight), animated: false)
}
}
}
if scrollView.contentOffset.y < headerViewHeight {
......
......@@ -50,7 +50,7 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
}
}
}
private lazy var topImageView: UIImageView = {
let view = UIImageView()
return view
......@@ -83,8 +83,11 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
button.clipsToBounds = true
return button
}()
var matchAgainEvent: (() -> Void)?
private let pageType: MatchResult
init(_ pageType: MatchResult) {
self.pageType = pageType
super.init(nibName: nil, bundle: nil)
......@@ -93,6 +96,25 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
@MainActor required init?(coder: NSCoder) {
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() {
super.viewDidLoad()
......@@ -141,7 +163,13 @@ class YHSurveyMatchResultViewController: YHBaseViewController {
}
@objc private func matchButtonClicked() {
//
if pageType == .success {
let vc = YHPlanViewController()
navigationController?.pushViewController(vc)
} else {
matchAgainEvent?()
navigationController?.popViewController()
}
}
/// 播放匹配成功
......
......@@ -10,6 +10,12 @@ import Lottie
import UIKit
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 = {
let aniView = LottieAnimationView(name: "survey_file_scan")
aniView.isUserInteractionEnabled = false
......@@ -49,7 +55,7 @@ class YHSurveyMatchingViewController: YHBaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
startAnimation()
startLoading()
}
private func setupUI() {
......@@ -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() {
lottieView.play(completion: { _ in
//
......
......@@ -45,6 +45,20 @@ class YHSurveySubmitDoneViewController: YHBaseViewController {
button.clipsToBounds = true
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() {
super.viewDidLoad()
......
......@@ -7,7 +7,91 @@
//
import UIKit
import SmartCodable
class YHPlanModel: NSObject {
class YHPlanListModel: SmartCodable {
var basic: YHPlanValueChartInfo = YHPlanValueChartInfo()
var list: [YHPlanAnalyzeModel] = []
var plan_article_case: [YHPlanCaseModel] = []
var plan_article_policy: [YHPlanCaseModel] = []
var code: String = ""
var url: String = ""
required init() {
}
}
class YHPlanCaseModel: SmartCodable {
var title: String = ""
var img_url: String = ""
var image_poster: String = ""
required init() {
}
}
class YHPlanValueChartInfo: SmartCodable {
var work_score: String = ""
var live_score: String = ""
var invest_score: String = ""
var stay_time_score: String = ""
var result: String = ""
var level_name: String = ""
required init() {
}
}
class YHPlanProductModel: SmartCodable {
var title: String = ""
var description: String = ""
var img_url: String = ""
var recommend_product_ids: [Int] = []
required init() {
}
}
class YHPlanAnalyzeModel: SmartCodable {
var name: String = ""
var score: String = "0.0"
var current_state: String = ""
var suggest: String = ""
var hong_kong_policy: String = ""
var solution_plan: [YHPlanProductModel] = []
func getTitle() -> String {
if name == "work" {
return "工作"
}
if name == "live" {
return "生活"
}
if name == "invest" {
return "投资"
}
if name == "stay" {
return "逗留"
}
return ""
}
required init() {
}
}
//
// 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
}
}
......@@ -26,7 +26,6 @@ class YHPlanAnalyzeInfoView: UIView {
lable.textAlignment = .left
lable.font = UIFont.PFSC_R(ofSize: 13)
lable.numberOfLines = 0
lable.text = "您目前尚未在香港搭建生活关联,基本无法提供在港生活相关证明资料"
return lable
}()
......@@ -64,7 +63,23 @@ class YHPlanAnalyzeInfoCell: UITableViewCell {
static let cellReuseIdentifier = "YHPlanAnalyzeInfoCell"
var products: [String] = [] {
var model = YHPlanAnalyzeModel() {
didSet {
titleLabel.text = "\(model.getTitle())分析"
let aa: ASAttributedString = .init("\(model.score)", .font(UIFont(name: "DINAlternate-Bold", size: 24)!), .foreground(UIColor.mainTextColor))
let bb: ASAttributedString = .init("/5.0", .font(UIFont(name: "DINAlternate-Bold", size: 14)!), .foreground(UIColor.init(hex: 0x8993A2)))
scoreLabel.attributed.text = aa+bb
currentStateVeiw.descLabel.text = model.current_state
requireVeiw.descLabel.text = model.hong_kong_policy
suggestVeiw.descLabel.text = model.suggest
products = model.solution_plan
}
}
var products: [YHPlanProductModel] = [] {
didSet {
let isShowList = products.count > 0
productListView.isHidden = !isShowList
......@@ -104,7 +119,7 @@ class YHPlanAnalyzeInfoCell: UITableViewCell {
let lable = UILabel()
lable.textAlignment = .right
lable.font = UIFont.PFSC_M(ofSize: 15)
let aa: ASAttributedString = .init("3.0", .font(UIFont(name: "DINAlternate-Bold", size: 24)!), .foreground(UIColor.mainTextColor))
let aa: ASAttributedString = .init("0.0", .font(UIFont(name: "DINAlternate-Bold", size: 24)!), .foreground(UIColor.mainTextColor))
let bb: ASAttributedString = .init("/5.0", .font(UIFont(name: "DINAlternate-Bold", size: 14)!), .foreground(UIColor.init(hex: 0x8993A2)))
lable.attributed.text = aa+bb
return lable
......
......@@ -12,6 +12,18 @@ class YHPlanCustomerCaseCollectionCell: UICollectionViewCell {
static let cellReuseIdentifier = "YHPlanCustomerCaseCollectionCell"
var model = YHPlanCaseModel() {
didSet {
descLabel.text = model.title
if let url = URL(string: model.img_url) {
iconImgV.sd_setImage(with: url, placeholderImage: UIImage(named: "global_default_image"))
} else {
iconImgV.image = UIImage(named: "global_default_image")
}
}
}
lazy var whiteContentView: UIView = {
let v = UIView()
v.backgroundColor = .white
......
......@@ -12,7 +12,7 @@ class YHPlanCustomerCaseListCell: UITableViewCell {
static let cellReuseIdentifier = "YHPlanCustomerCaseListCell"
var cases: [String] = [] {
var cases: [YHPlanCaseModel] = [] {
didSet {
collectionView.reloadData()
}
......@@ -105,7 +105,12 @@ extension YHPlanCustomerCaseListCell: UICollectionViewDelegate, UICollectionView
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let cellWidth = floor((KScreenWidth-16.0*2.0-10.0)/2.0)
var height = self.getHeigt(font: UIFont.PFSC_R(ofSize: 14), width: cellWidth-8.0*2.0, string: cases[indexPath.item])
var height = 0.0
if indexPath.item < cases.count {
let model = cases[indexPath.item]
height = self.getHeigt(font: UIFont.PFSC_R(ofSize: 14), width: cellWidth-8.0*2.0, string: model.title)
}
height += (cellWidth*(200.0/166.0) + 8.0+12.0+10.0)
return CGSize(width: cellWidth, height: height)
}
......@@ -116,7 +121,8 @@ extension YHPlanCustomerCaseListCell: UICollectionViewDelegate, UICollectionView
return UICollectionViewCell()
}
if 0 <= indexPath.item && indexPath.item < cases.count {
cell.descLabel.text = cases[indexPath.item]
let model = cases[indexPath.item]
cell.model = model
}
return cell
}
......
......@@ -13,6 +13,16 @@ class YHPlanPolicyCarouselImageCell: FSPagerViewCell {
static let cellReuseIdentifier = "YHPlanPolicyCarouselImageCell"
var model = YHPlanCaseModel() {
didSet {
if let url = URL(string: model.img_url) {
imageV.sd_setImage(with: url, placeholderImage: UIImage(named: "global_default_image"))
} else {
imageV.image = UIImage(named: "global_default_image")
}
}
}
lazy var imageV: UIImageView = {
let v = UIImageView()
return v
......
......@@ -11,7 +11,7 @@ import FSPagerView
class YHPlanPolicyCarouselView: UIView {
var bannerArr: [String] = [] {
var bannerArr: [YHPlanCaseModel] = [] {
didSet {
// 设置为0是先停掉自动滑动定时器
bannerView.automaticSlidingInterval = 0
......@@ -128,7 +128,7 @@ extension YHPlanPolicyCarouselView: FSPagerViewDataSource, FSPagerViewDelegate {
}
if index < bannerArr.count {
let model = bannerArr[index]
cell.imageV.backgroundColor = .randomColor()
cell.model = model
}
return cell
}
......
......@@ -85,12 +85,20 @@ class YHPlanProductItemView: UIView {
class YHPlanProductListView: UIView {
var products: [String] = [] {
var products: [YHPlanProductModel] = [] {
didSet {
listView.removeSubviews()
var lastItemView: YHPlanProductItemView?
for (index, item) in products.enumerated() {
let v = YHPlanProductItemView(frame: .zero)
v.titleLabel.text = item.title
v.descLabel.text = item.description
if let url = URL(string: item.img_url) {
v.iconImgV.sd_setImage(with: url, placeholderImage: UIImage(named: "global_default_image"))
} else {
v.iconImgV.image = UIImage(named: "global_default_image")
}
listView.addSubview(v)
v.snp.makeConstraints { make in
make.left.right.equalToSuperview()
......
......@@ -11,6 +11,12 @@ import UIKit
class YHPlanScoreCell: UITableViewCell {
static let cellReuseIdentifier = "YHPlanScoreCell"
var model = YHPlanValueChartInfo() {
didSet {
scoreView.model = model
}
}
lazy var scoreView: YHPlanScoreView = {
let v = YHPlanScoreView(frame: .zero)
......@@ -35,6 +41,5 @@ class YHPlanScoreCell: UITableViewCell {
scoreView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
scoreView.chartView.updateScores([5.0, 5.0, 5.0, 5.0])
}
}
......@@ -9,6 +9,19 @@
import UIKit
class YHPlanScoreView: UIView {
var model = YHPlanValueChartInfo() {
didSet {
let score1 = CGFloat(Double(model.work_score) ?? 0.0)
let score2 = CGFloat(Double(model.live_score) ?? 0.0)
let score3 = CGFloat(Double(model.invest_score) ?? 0.0)
let score4 = CGFloat(Double(model.stay_time_score) ?? 0.0)
chartView.updateScores([score1, score2, score3, score4])
statusLabel.text = model.level_name
descLabel.text = model.result
}
}
lazy var whiteContentView: UIView = {
let v = UIView()
......@@ -40,7 +53,7 @@ class YHPlanScoreView: UIView {
lable.textColor = UIColor.mainTextColor
lable.textAlignment = .center
lable.font = UIFont(name: "AlibabaPuHuiTi_3_95_ExtraBold", size: 24)
lable.text = ""
lable.text = ""
return lable
}()
......@@ -61,7 +74,6 @@ class YHPlanScoreView: UIView {
lable.textAlignment = .left
lable.font = UIFont.PFSC_R(ofSize: 13)
lable.numberOfLines = 0
lable.text = "您已获得香港居民身份,办理项目为高才计划,根据您得情况综合分析结果如下:这是一段文字描述"
return lable
}()
......
......@@ -6,6 +6,7 @@
// Copyright © 2025 https://www.galaxy-immi.com. All rights reserved.
//
import AttributedString
import UIKit
class YHSurveyTableViewCell: YHResignDocumentCell {
......@@ -35,6 +36,15 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
stack.distribution = .fillProportionally
return stack
}()
private lazy var infoFailLabel: UILabel = {
let label = UILabel()
label.font = .PFSC_R(ofSize: 12)
label.textColor = .failColor
label.text = "请选择"
label.isHidden = true
return label
}()
// MARK: - Properties
......@@ -58,6 +68,7 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
updateCellCorner(.single)
subContainerView.addSubview(questionLabel)
subContainerView.addSubview(optionsStackView)
subContainerView.addSubview(infoFailLabel)
questionLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(24)
......@@ -71,12 +82,25 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
make.right.equalToSuperview().offset(-18)
make.bottom.equalToSuperview().offset(-24).priority(.high)
}
infoFailLabel.snp.makeConstraints { make in
make.left.equalTo(questionLabel)
make.right.lessThanOrEqualToSuperview().offset(-18)
make.bottom.equalToSuperview().offset(-24).priority(.high)
}
infoFailLabel.isHidden = true
}
// MARK: - Configuration
func configure(with question: String, options: [String], selectedIndex: Int? = nil, type: QuestionType = .singleChoice) {
questionLabel.text = question
func configure(with question: String, isRequired: Bool = true, options: [String], selectedIndices: [Int], type: QuestionType = .singleChoice, needShowFailButton: Bool = false) {
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
// Clear previous options
......@@ -84,45 +108,103 @@ class YHSurveyTableViewCell: YHResignDocumentCell {
// Add new options
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)
}
updateFailState(needShowFailButton)
}
private func updateFailState(_ needShowFailButton: Bool = false) {
if needShowFailButton {
optionsStackView.snp.remakeConstraints { make in
make.top.equalTo(questionLabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(28)
make.right.equalToSuperview().offset(-18)
}
infoFailLabel.snp.remakeConstraints { make in
make.top.equalTo(optionsStackView.snp.bottom).offset(8)
make.left.equalTo(questionLabel)
make.right.lessThanOrEqualToSuperview().offset(-18)
make.bottom.equalToSuperview().offset(-24).priority(.high)
}
infoFailLabel.isHidden = false
} else {
optionsStackView.snp.remakeConstraints { make in
make.top.equalTo(questionLabel.snp.bottom).offset(16)
make.left.equalToSuperview().offset(28)
make.right.equalToSuperview().offset(-18)
make.bottom.equalToSuperview().offset(-24).priority(.high)
}
infoFailLabel.snp.remakeConstraints { make in
make.left.equalTo(questionLabel)
make.right.lessThanOrEqualToSuperview().offset(-18)
make.bottom.equalToSuperview().offset(-24).priority(.high)
}
infoFailLabel.isHidden = true
}
}
private func createOptionView(text: String, isSelected: Bool, index: Int) -> UIView {
let container = UIControl()
container.tag = index
container.addTarget(self, action: #selector(optionButtonTapped(_:)), for: .touchUpInside)
let item = YHSurveyQuestionItemView()
item.tag = index
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()
label.text = text
label.textColor = .mainTextColor
label.font = .PFSC_R(ofSize: 14)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(iconView)
addSubview(contentLabel)
let icon = UIImageView()
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
iconView.snp.makeConstraints { make in
make.left.centerY.equalToSuperview()
make.width.height.equalTo(14)
}
label.snp.makeConstraints { make in
make.left.equalTo(icon.snp.right).offset(8)
contentLabel.snp.makeConstraints { make in
make.left.equalTo(iconView.snp.right).offset(8)
make.right.top.bottom.equalToSuperview()
}
return container
}
// MARK: - Actions
@objc private func optionButtonTapped(_ sender: UIControl) {
optionSelected?(sender.tag)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
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")
}
}
......@@ -8,6 +8,34 @@
import UIKit
class YHPlanViewModel: NSObject {
class YHPlanViewModel: YHBaseViewModel {
var planListModel: YHPlanListModel = YHPlanListModel()
func requetResignPlanInfo(callBackBlock: @escaping (_ success: Bool, _ error: YHErrorModel?) -> Void) {
let strUrl = YHBaseUrlManager.shared.curURL() + YHAllApiName.ResignPlan.planlistApi
_ = YHNetRequest.getRequest(url: strUrl) { [weak self] json, _ in
guard let self = self else { return }
// 1. json字符串 转 对象
if json.code == 200 {
guard let dic = json.data?.peel as? [String: Any], let result = YHPlanListModel.deserialize(from: dic) else {
callBackBlock(false, nil)
return
}
self.planListModel = result
callBackBlock(true, nil)
} else {
// self.activityTravelModel = nil
let error: YHErrorModel = YHErrorModel(errorCode: Int32(json.code), errorMsg: json.msg)
callBackBlock(false, error)
}
} failBlock: { err in
// self.activityTravelModel = nil
callBackBlock(false, err)
}
}
}
//
// 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)
}
}
}
......@@ -752,4 +752,16 @@ class YHAllApiName {
}
// 续签方案
struct ResignPlan {
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" : "survey_share_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "survey_share_icon@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