parent
94c2315894
commit
15ba209901
|
|
@ -297,6 +297,7 @@
|
||||||
30EFF3E72FDAA93D00EB35D4 /* PrivacyPolicyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EFF3E62FDAA93D00EB35D4 /* PrivacyPolicyView.swift */; };
|
30EFF3E72FDAA93D00EB35D4 /* PrivacyPolicyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30EFF3E62FDAA93D00EB35D4 /* PrivacyPolicyView.swift */; };
|
||||||
30EFF3E82FCA8C7000227D26 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30EFF3E92FCA8C7000227D26 /* AuthenticationServices.framework */; };
|
30EFF3E82FCA8C7000227D26 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30EFF3E92FCA8C7000227D26 /* AuthenticationServices.framework */; };
|
||||||
55BF752D2FFE53F70055DA57 /* LocationPermissionPopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */; };
|
55BF752D2FFE53F70055DA57 /* LocationPermissionPopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */; };
|
||||||
|
55BF75352FFF91690055DA57 /* InteractionEmojiCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BF75342FFF91690055DA57 /* InteractionEmojiCell.swift */; };
|
||||||
D698E9C56D6F2C152772131D /* Pods_QuickLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */; };
|
D698E9C56D6F2C152772131D /* Pods_QuickLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
|
@ -604,6 +605,7 @@
|
||||||
3E4359082FC48D26003470A5 /* QuickLocation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuickLocation.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
3E4359082FC48D26003470A5 /* QuickLocation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = QuickLocation.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QuickLocation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
475D33CAFA1E1911EB1F8D9F /* Pods_QuickLocation.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QuickLocation.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionPopView.swift; sourceTree = "<group>"; };
|
55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionPopView.swift; sourceTree = "<group>"; };
|
||||||
|
55BF75342FFF91690055DA57 /* InteractionEmojiCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractionEmojiCell.swift; sourceTree = "<group>"; };
|
||||||
DA16D49AA46D4F6838340B55 /* Pods-QuickLocation.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.debug.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.debug.xcconfig"; sourceTree = "<group>"; };
|
DA16D49AA46D4F6838340B55 /* Pods-QuickLocation.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.debug.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
E483B9929C03809ADEDE8341 /* Pods-QuickLocation.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.release.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.release.xcconfig"; sourceTree = "<group>"; };
|
E483B9929C03809ADEDE8341 /* Pods-QuickLocation.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickLocation.release.xcconfig"; path = "Target Support Files/Pods-QuickLocation/Pods-QuickLocation.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
@ -1012,6 +1014,7 @@
|
||||||
30A7A9102FCAEE3D00105780 /* GroupListPopView.swift */,
|
30A7A9102FCAEE3D00105780 /* GroupListPopView.swift */,
|
||||||
30D87CDE2FDFF1A100E958FD /* QuickMessageView.swift */,
|
30D87CDE2FDFF1A100E958FD /* QuickMessageView.swift */,
|
||||||
30D87CDC2FDFF07500E958FD /* InteractionView.swift */,
|
30D87CDC2FDFF07500E958FD /* InteractionView.swift */,
|
||||||
|
55BF75342FFF91690055DA57 /* InteractionEmojiCell.swift */,
|
||||||
55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */,
|
55BF752C2FFE53F70055DA57 /* LocationPermissionPopView.swift */,
|
||||||
30A87A692FEF59E60095E7C6 /* SearchLocation */,
|
30A87A692FEF59E60095E7C6 /* SearchLocation */,
|
||||||
30A87A5C2FEE711C0095E7C6 /* Bubble */,
|
30A87A5C2FEE711C0095E7C6 /* Bubble */,
|
||||||
|
|
@ -1864,6 +1867,7 @@
|
||||||
30EFF3DA2FDA935D00EB35D4 /* EmergencyContactFooterView.swift in Sources */,
|
30EFF3DA2FDA935D00EB35D4 /* EmergencyContactFooterView.swift in Sources */,
|
||||||
3062E8C22FCFB86800CEF511 /* CreateGroupViewModel.swift in Sources */,
|
3062E8C22FCFB86800CEF511 /* CreateGroupViewModel.swift in Sources */,
|
||||||
30A87A662FEE843E0095E7C6 /* CreateBubbleDoneView.swift in Sources */,
|
30A87A662FEE843E0095E7C6 /* CreateBubbleDoneView.swift in Sources */,
|
||||||
|
55BF75352FFF91690055DA57 /* InteractionEmojiCell.swift in Sources */,
|
||||||
305A769B2FCA8C7000227D26 /* PopupAnimators.swift in Sources */,
|
305A769B2FCA8C7000227D26 /* PopupAnimators.swift in Sources */,
|
||||||
30A87A4D2FEE1DB40095E7C6 /* ItineraryDetailView.swift in Sources */,
|
30A87A4D2FEE1DB40095E7C6 /* ItineraryDetailView.swift in Sources */,
|
||||||
305A769C2FCA8C7000227D26 /* PopupViewController.swift in Sources */,
|
305A769C2FCA8C7000227D26 /* PopupViewController.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
guard let result = resultDic,
|
guard let result = resultDic,
|
||||||
let resultStatus = result["resultStatus"] as? String,
|
let resultStatus = result["resultStatus"] as? String,
|
||||||
resultStatus != "6001" else { return }
|
resultStatus != "6001" else { return }
|
||||||
|
if resultStatus == "9000" {
|
||||||
|
NotificationCenter.default.post(name: .RequestOrderPayStatusNotification, object: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Contents.json
vendored
Normal file
22
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group_2206@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group_2206@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Group_2206@2x.png
vendored
Normal file
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Group_2206@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Group_2206@3x.png
vendored
Normal file
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_member_tips.imageset/Group_2206@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 306 KiB |
22
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Contents.json
vendored
Normal file
22
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group_2207@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Group_2207@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Group_2207@2x.png
vendored
Normal file
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Group_2207@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 150 KiB |
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Group_2207@3x.png
vendored
Normal file
BIN
QuickLocation/Assets.xcassets/GroupMemberList/mask_self_tips.imageset/Group_2207@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 297 KiB |
|
|
@ -114,7 +114,7 @@ extension ApiManager {
|
||||||
handlePopView(message)
|
handlePopView(message)
|
||||||
default:
|
default:
|
||||||
// 接口没返回code的时候取success字段
|
// 接口没返回code的时候取success字段
|
||||||
if success != nil, success == true {
|
if success != nil {
|
||||||
if let decrypted = decryptedData {
|
if let decrypted = decryptedData {
|
||||||
let decryptedResponse = Response(statusCode: response.statusCode,
|
let decryptedResponse = Response(statusCode: response.statusCode,
|
||||||
data: decrypted,
|
data: decrypted,
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,32 @@ class GroupMemberListVC: BaseViewController {
|
||||||
reactiveAction()
|
reactiveAction()
|
||||||
|
|
||||||
requestGroupInfo()
|
requestGroupInfo()
|
||||||
|
|
||||||
|
guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return }
|
||||||
|
rootView.unlockVipMaskView.isHidden = true
|
||||||
|
if AppContextManager.shared.vip == 1 {
|
||||||
|
rootView.tipsImg.image = UIImage(named: "GroupMemberList/mask_tips")
|
||||||
|
rootView.unlockVipMaskView.isHidden = false
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationCenter.default.rx.notification(.RequestOrderPayStatusNotification)
|
||||||
|
.subscribe(onNext: { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.rootView.unlockVipMaskView.isHidden = true
|
||||||
|
if AppContextManager.shared.vip == 1 {
|
||||||
|
self.rootView.tipsImg.image = UIImage(named: "GroupMemberList/mask_tips")
|
||||||
|
self.rootView.unlockVipMaskView.isHidden = false
|
||||||
|
} else {
|
||||||
|
self.rootView.refreshVipState()
|
||||||
|
}
|
||||||
|
}).disposed(by: disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
guard let systemConfig = AppContextManager.shared.systemConfig, systemConfig.globalDisplay else { return }
|
// rootView.selectedDate.accept(Date())
|
||||||
rootView.unlockVipMaskView.isHidden = AppContextManager.shared.vip > 1
|
// rootView.scrollToToday()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func reactiveAction() {
|
private func reactiveAction() {
|
||||||
|
|
@ -68,8 +87,10 @@ class GroupMemberListVC: BaseViewController {
|
||||||
rootView.selectedDate
|
rootView.selectedDate
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.subscribe(onNext: { [weak self] date in
|
.subscribe(onNext: { [weak self] date in
|
||||||
self?.rootView.scrollReportToTop()
|
guard let self = self else { return }
|
||||||
self?.requestDrivingEvents(for: date)
|
self.rootView.scrollReportToTop()
|
||||||
|
guard !self.rootView.isSelectedDateLocked else { return }
|
||||||
|
self.requestDrivingEvents(for: date)
|
||||||
}).disposed(by: disposeBag)
|
}).disposed(by: disposeBag)
|
||||||
|
|
||||||
// 成员点击 → 重置日期到当天(selectedDate 发射 → 自动触发 API 请求)
|
// 成员点击 → 重置日期到当天(selectedDate 发射 → 自动触发 API 请求)
|
||||||
|
|
@ -78,6 +99,7 @@ class GroupMemberListVC: BaseViewController {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.viewModel.memberId = model.user_id
|
self.viewModel.memberId = model.user_id
|
||||||
self.rootView.selectedMemberIsSelf = self.viewModel.isCurrentUser(id: model.user_id)
|
self.rootView.selectedMemberIsSelf = self.viewModel.isCurrentUser(id: model.user_id)
|
||||||
|
self.rootView.unlockVipMaskView.isHidden = true
|
||||||
self.rootView.selectedDate.accept(Date())
|
self.rootView.selectedDate.accept(Date())
|
||||||
self.rootView.scrollToToday()
|
self.rootView.scrollToToday()
|
||||||
self.rootView.scrollReportToTop()
|
self.rootView.scrollReportToTop()
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ class GroupMemberListView: UIView {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// MARK: - 未解锁会员遮罩
|
// MARK: - 未解锁会员遮罩
|
||||||
|
var tipsImg: UIImageView!
|
||||||
lazy var unlockVipMaskView: UIView = {
|
lazy var unlockVipMaskView: UIView = {
|
||||||
let view = UIView()
|
let view = UIView()
|
||||||
view.backgroundColor = .clear
|
view.backgroundColor = .clear
|
||||||
|
|
@ -176,7 +177,7 @@ class GroupMemberListView: UIView {
|
||||||
view.addSubview(maskBg)
|
view.addSubview(maskBg)
|
||||||
maskBg.layoutChain.edges()
|
maskBg.layoutChain.edges()
|
||||||
|
|
||||||
let tipsImg = UIImageView(image: UIImage(named: "GroupMemberList/mask_tips"))
|
tipsImg = UIImageView(image: UIImage(named: "GroupMemberList/mask_tips"))
|
||||||
view.addSubview(tipsImg)
|
view.addSubview(tipsImg)
|
||||||
tipsImg.layoutChain
|
tipsImg.layoutChain
|
||||||
.top(83)
|
.top(83)
|
||||||
|
|
@ -296,6 +297,12 @@ class GroupMemberListView: UIView {
|
||||||
// MARK: - 日期
|
// MARK: - 日期
|
||||||
private var dateItems: [DateItem] = []
|
private var dateItems: [DateItem] = []
|
||||||
let selectedDate = BehaviorRelay<Date>(value: Date())
|
let selectedDate = BehaviorRelay<Date>(value: Date())
|
||||||
|
var isSelectedDateLocked: Bool {
|
||||||
|
let today = Date()
|
||||||
|
let calendar = Calendar.current
|
||||||
|
let daysAgo = calendar.dateComponents([.day], from: selectedDate.value, to: today).day ?? 0
|
||||||
|
return maxSelectableDays > 0 && daysAgo > maxSelectableDays - 1
|
||||||
|
}
|
||||||
private let daysPerPage = 7
|
private let daysPerPage = 7
|
||||||
|
|
||||||
/// 当前选中的成员是否是自己
|
/// 当前选中的成员是否是自己
|
||||||
|
|
@ -309,6 +316,7 @@ class GroupMemberListView: UIView {
|
||||||
let isToday: Bool
|
let isToday: Bool
|
||||||
let isFuture: Bool
|
let isFuture: Bool
|
||||||
let isSelectable: Bool
|
let isSelectable: Bool
|
||||||
|
let isLocked: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 根据 VIP 和成员关系计算最大可查询天数
|
/// 根据 VIP 和成员关系计算最大可查询天数
|
||||||
|
|
@ -326,15 +334,24 @@ class GroupMemberListView: UIView {
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
let today = Date()
|
let today = Date()
|
||||||
let maxDays = maxSelectableDays
|
let maxDays = maxSelectableDays
|
||||||
|
let hasAccess = maxDays > 0
|
||||||
dateItems = dateItems.map { item in
|
dateItems = dateItems.map { item in
|
||||||
let daysAgo = calendar.dateComponents([.day], from: item.date, to: today).day ?? 0
|
let daysAgo = calendar.dateComponents([.day], from: item.date, to: today).day ?? 0
|
||||||
return DateItem(date: item.date, day: item.day, isToday: item.isToday,
|
let inFreeRange = daysAgo <= maxDays - 1
|
||||||
|
return DateItem(date: item.date, day: item.day,
|
||||||
|
isToday: item.isToday,
|
||||||
isFuture: item.isFuture,
|
isFuture: item.isFuture,
|
||||||
isSelectable: maxDays > 0 && !item.isFuture && daysAgo <= maxDays - 1)
|
isSelectable: hasAccess && !item.isFuture,
|
||||||
|
isLocked: hasAccess && !item.isFuture && !inFreeRange)
|
||||||
}
|
}
|
||||||
dateCollectionView.reloadData()
|
dateCollectionView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func refreshVipState() {
|
||||||
|
updateDateSelectability()
|
||||||
|
selectedDate.accept(Date())
|
||||||
|
}
|
||||||
|
|
||||||
private func generateDateItems() {
|
private func generateDateItems() {
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
let today = Date()
|
let today = Date()
|
||||||
|
|
@ -349,10 +366,13 @@ class GroupMemberListView: UIView {
|
||||||
let day = calendar.component(.day, from: date)
|
let day = calendar.component(.day, from: date)
|
||||||
let isFuture = date > today
|
let isFuture = date > today
|
||||||
let daysAgo = calendar.dateComponents([.day], from: date, to: today).day ?? 0
|
let daysAgo = calendar.dateComponents([.day], from: date, to: today).day ?? 0
|
||||||
|
let hasAccess = maxSelectableDays > 0
|
||||||
|
let inFreeRange = hasAccess && daysAgo <= maxSelectableDays - 1
|
||||||
return DateItem(date: date, day: day,
|
return DateItem(date: date, day: day,
|
||||||
isToday: calendar.isDateInToday(date),
|
isToday: calendar.isDateInToday(date),
|
||||||
isFuture: isFuture,
|
isFuture: isFuture,
|
||||||
isSelectable: maxSelectableDays > 0 && !isFuture && daysAgo <= maxSelectableDays - 1)
|
isSelectable: hasAccess && !isFuture,
|
||||||
|
isLocked: hasAccess && !isFuture && !inFreeRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -602,6 +622,16 @@ extension GroupMemberListView: UICollectionViewDataSource, UICollectionViewDeleg
|
||||||
guard collectionView == dateCollectionView else { return }
|
guard collectionView == dateCollectionView else { return }
|
||||||
let item = dateItems[indexPath.row]
|
let item = dateItems[indexPath.row]
|
||||||
guard item.isSelectable else { return }
|
guard item.isSelectable else { return }
|
||||||
|
|
||||||
|
if item.isLocked {
|
||||||
|
tipsImg.image = selectedMemberIsSelf
|
||||||
|
? UIImage(named: "GroupMemberList/mask_self_tips")
|
||||||
|
: UIImage(named: "GroupMemberList/mask_member_tips")
|
||||||
|
unlockVipMaskView.isHidden = false
|
||||||
|
} else {
|
||||||
|
unlockVipMaskView.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
let oldDate = selectedDate.value
|
let oldDate = selectedDate.value
|
||||||
selectedDate.accept(item.date)
|
selectedDate.accept(item.date)
|
||||||
if let oldRow = dateItems.firstIndex(where: { Calendar.current.isDate($0.date, inSameDayAs: oldDate) }),
|
if let oldRow = dateItems.firstIndex(where: { Calendar.current.isDate($0.date, inSameDayAs: oldDate) }),
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,7 @@ class HomeViewController: BaseViewController {
|
||||||
// 导航按钮回调
|
// 导航按钮回调
|
||||||
rootView.interactionView.onNavigate = { [weak self] in
|
rootView.interactionView.onNavigate = { [weak self] in
|
||||||
guard let self = self, let member = self.rootView.interactionView.currentMember else { return }
|
guard let self = self, let member = self.rootView.interactionView.currentMember else { return }
|
||||||
|
self.rootView.dismissMemberPanel()
|
||||||
let userCoord = self.lastLocation?.coordinate
|
let userCoord = self.lastLocation?.coordinate
|
||||||
let groupName = self.viewModel.groupName
|
let groupName = self.viewModel.groupName
|
||||||
let model = self.viewModel.groupModel
|
let model = self.viewModel.groupModel
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
//
|
||||||
|
// InteractionEmojiCell.swift
|
||||||
|
// QuickLocation
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class InteractionEmojiCell: UICollectionViewCell {
|
||||||
|
|
||||||
|
static let normalPngMap: [String: String] = [
|
||||||
|
"normal_1": "cold-face-emoji-103", "normal_10": "nervous-face-emoji-121",
|
||||||
|
"normal_11": "phone-call-141", "normal_12": "question-face-emoji-167",
|
||||||
|
"normal_13": "chill-face-emoji-073", "normal_14": "driving-face-emoji-085",
|
||||||
|
"normal_15": "heart-eyes-107", "normal_16": "house-face-emoji-169",
|
||||||
|
"normal_17": "lifiting-face-emoji-111","normal_18": "like-face-emoji-077",
|
||||||
|
"normal_19": "looking-face-emoji-137","normal_2": "crying-face-emoji-121",
|
||||||
|
"normal_20": "no-face-emoji-133", "normal_21": "party-face-emoji-078",
|
||||||
|
"normal_22": "plane-face-emoji-124", "normal_23": "rose-face-emoji-114",
|
||||||
|
"normal_24": "sleep-face-emoji-091", "normal_3": "dizzy-face-emoji-118",
|
||||||
|
"normal_4": "broken-face-emoji-142", "normal_5": "angry-face-emoji-027",
|
||||||
|
"normal_6": "eating-popcorn-073", "normal_7": "face-using-laptop-009",
|
||||||
|
"normal_8": "hi-face-emoji-129", "normal_9": "laughing-face-emoji-136",
|
||||||
|
]
|
||||||
|
|
||||||
|
static let funPngMap: [String: String] = [
|
||||||
|
"fun_10": "10-020", "fun_11": "11-043", "fun_13": "13-005", "fun_14": "14-145",
|
||||||
|
"fun_15": "15-073", "fun_16": "16-031", "fun_17": "17-034", "fun_18": "18-092",
|
||||||
|
"fun_19": "19-124", "fun_2": "2-002", "fun_3": "3-029", "fun_4": "4-005",
|
||||||
|
"fun_5": "5-046", "fun_6": "6-021", "fun_7": "7-030", "fun_8": "8-033",
|
||||||
|
"fun_9": "9-166",
|
||||||
|
]
|
||||||
|
|
||||||
|
static let normalFileNames: [String] = normalPngMap.keys.sorted()
|
||||||
|
static let funFileNames: [String] = funPngMap.keys.sorted()
|
||||||
|
|
||||||
|
private let imageView: UIImageView = {
|
||||||
|
let v = UIImageView()
|
||||||
|
v.contentMode = .scaleAspectFit
|
||||||
|
return v
|
||||||
|
}()
|
||||||
|
|
||||||
|
let lockView: UIImageView = {
|
||||||
|
let iv = UIImageView(image: UIImage(named: "Common/lock"))
|
||||||
|
iv.isHidden = true
|
||||||
|
return iv
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
contentView.addSubview(imageView)
|
||||||
|
contentView.addSubview(lockView)
|
||||||
|
imageView.layoutChain.edges()
|
||||||
|
lockView.layoutChain
|
||||||
|
.bottom(1)
|
||||||
|
.right(1)
|
||||||
|
.width(16)
|
||||||
|
.height(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func configure(name: String) {
|
||||||
|
let isNormal = name.hasPrefix("normal_")
|
||||||
|
let map = isNormal ? Self.normalPngMap : Self.funPngMap
|
||||||
|
let base = isNormal ? "normal" : "fun"
|
||||||
|
if let pngName = map[name],
|
||||||
|
// let path = Bundle.main.path(forResource: "lotties/emoji/\(base)/png/\(pngName)", ofType: "png") {
|
||||||
|
let path = Bundle.main.path(forResource: "\(pngName)", ofType: "png") {
|
||||||
|
imageView.image = UIImage(contentsOfFile: path)
|
||||||
|
}
|
||||||
|
lockView.isHidden = AppContextManager.shared.vip > 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -44,8 +44,7 @@ class InteractionView: UIView {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 当前表情列表(normal / fun)
|
/// 当前表情列表(normal / fun)
|
||||||
private let emojiRelay = BehaviorRelay<[String]>(value: UIView.emojiFileNames)
|
private let emojiRelay = BehaviorRelay<[String]>(value: InteractionEmojiCell.normalFileNames)
|
||||||
private var emojiPlaybackGeneration = 0
|
|
||||||
private var isShowingFunEmoji = false
|
private var isShowingFunEmoji = false
|
||||||
|
|
||||||
private func setupRx() {
|
private func setupRx() {
|
||||||
|
|
@ -64,6 +63,7 @@ class InteractionView: UIView {
|
||||||
|
|
||||||
navigateBtn.rx.tap
|
navigateBtn.rx.tap
|
||||||
.subscribe(onNext: { [weak self] _ in
|
.subscribe(onNext: { [weak self] _ in
|
||||||
|
|
||||||
self?.onNavigate?()
|
self?.onNavigate?()
|
||||||
})
|
})
|
||||||
.disposed(by: disposeBag)
|
.disposed(by: disposeBag)
|
||||||
|
|
@ -104,7 +104,6 @@ class InteractionView: UIView {
|
||||||
emojiRelay
|
emojiRelay
|
||||||
.subscribe(onNext: { [weak self] items in
|
.subscribe(onNext: { [weak self] items in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.stopVisibleEmojiAnimations()
|
|
||||||
let pages = (items.count + InteractionView.emojiPerPage - 1) / InteractionView.emojiPerPage
|
let pages = (items.count + InteractionView.emojiPerPage - 1) / InteractionView.emojiPerPage
|
||||||
self.emojiPageControl.numberOfPages = max(pages, 1)
|
self.emojiPageControl.numberOfPages = max(pages, 1)
|
||||||
self.emojiPageControl.currentPage = 0
|
self.emojiPageControl.currentPage = 0
|
||||||
|
|
@ -119,27 +118,19 @@ class InteractionView: UIView {
|
||||||
private func switchEmojiCategory(isFun: Bool) {
|
private func switchEmojiCategory(isFun: Bool) {
|
||||||
guard isShowingFunEmoji != isFun else { return }
|
guard isShowingFunEmoji != isFun else { return }
|
||||||
isShowingFunEmoji = isFun
|
isShowingFunEmoji = isFun
|
||||||
stopVisibleEmojiAnimations()
|
|
||||||
normalBg.isHidden = !isFun
|
normalBg.isHidden = !isFun
|
||||||
interestBg.isHidden = isFun
|
interestBg.isHidden = isFun
|
||||||
emojiRelay.accept(isFun ? UIView.funEmojiFileNames : UIView.emojiFileNames)
|
emojiRelay.accept(isFun ? InteractionEmojiCell.funFileNames : InteractionEmojiCell.normalFileNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy var dataSource: RxCollectionViewSectionedReloadDataSource<SectionModel<String, String>> = {
|
private lazy var dataSource: RxCollectionViewSectionedReloadDataSource<SectionModel<String, String>> = {
|
||||||
RxCollectionViewSectionedReloadDataSource<SectionModel<String, String>> { _, collectionView, indexPath, name in
|
RxCollectionViewSectionedReloadDataSource<SectionModel<String, String>> { _, collectionView, indexPath, name in
|
||||||
let cell: EmojiPanelCell = collectionView.dequeueReusableCell(for: indexPath)
|
let cell: InteractionEmojiCell = collectionView.dequeueReusableCell(for: indexPath)
|
||||||
cell.configure(name: name)
|
cell.configure(name: name)
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private func stopVisibleEmojiAnimations() {
|
|
||||||
emojiPlaybackGeneration += 1
|
|
||||||
emojiCollectionView.visibleCells.forEach { cell in
|
|
||||||
(cell as? EmojiPanelCell)?.stopAnimation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func setupUI() {
|
private func setupUI() {
|
||||||
addSubview(infoView)
|
addSubview(infoView)
|
||||||
infoView.addSubview(headerBgView)
|
infoView.addSubview(headerBgView)
|
||||||
|
|
@ -476,7 +467,7 @@ class InteractionView: UIView {
|
||||||
cv.isPagingEnabled = true
|
cv.isPagingEnabled = true
|
||||||
cv.bounces = false
|
cv.bounces = false
|
||||||
cv.showsHorizontalScrollIndicator = false
|
cv.showsHorizontalScrollIndicator = false
|
||||||
cv.register(EmojiPanelCell.self)
|
cv.register(InteractionEmojiCell.self)
|
||||||
cv.delegate = self
|
cv.delegate = self
|
||||||
return cv
|
return cv
|
||||||
}()
|
}()
|
||||||
|
|
@ -488,7 +479,7 @@ class InteractionView: UIView {
|
||||||
|
|
||||||
lazy var emojiPageControl: UIPageControl = {
|
lazy var emojiPageControl: UIPageControl = {
|
||||||
let pc = UIPageControl()
|
let pc = UIPageControl()
|
||||||
pc.numberOfPages = (UIView.emojiFileNames.count + InteractionView.emojiPerPage - 1) / InteractionView.emojiPerPage
|
pc.numberOfPages = (InteractionEmojiCell.normalFileNames.count + InteractionView.emojiPerPage - 1) / InteractionView.emojiPerPage
|
||||||
pc.currentPageIndicatorTintColor = UIColor(hexStr: "#16B3FF")
|
pc.currentPageIndicatorTintColor = UIColor(hexStr: "#16B3FF")
|
||||||
pc.pageIndicatorTintColor = UIColor(hexStr: "#7AD6FF", alpha: 0.4)
|
pc.pageIndicatorTintColor = UIColor(hexStr: "#7AD6FF", alpha: 0.4)
|
||||||
return pc
|
return pc
|
||||||
|
|
@ -519,16 +510,6 @@ extension InteractionView: UICollectionViewDelegate {
|
||||||
let page = Int(scrollView.contentOffset.x / scrollView.bounds.width)
|
let page = Int(scrollView.contentOffset.x / scrollView.bounds.width)
|
||||||
emojiPageControl.currentPage = page
|
emojiPageControl.currentPage = page
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
|
|
||||||
guard collectionView == emojiCollectionView else { return }
|
|
||||||
(cell as? EmojiPanelCell)?.playAnimation()
|
|
||||||
}
|
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
|
|
||||||
guard collectionView == emojiCollectionView else { return }
|
|
||||||
(cell as? EmojiPanelCell)?.stopAnimation()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - EmojiPanelCell
|
// MARK: - EmojiPanelCell
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,36 @@ class PromotionalActivitiesVC: BaseViewController {
|
||||||
rootView.confirmBtn.rx.tap.subscribe(onNext: { _ in
|
rootView.confirmBtn.rx.tap.subscribe(onNext: { _ in
|
||||||
self.requestOrderPayParams()
|
self.requestOrderPayParams()
|
||||||
}).disposed(by: disposeBag)
|
}).disposed(by: disposeBag)
|
||||||
|
|
||||||
|
NotificationCenter.default.rx.notification(.RequestOrderPayStatusNotification)
|
||||||
|
.subscribe(onNext: { [weak self] _ in
|
||||||
|
self?.handlePaymentSuccess()
|
||||||
|
}).disposed(by: disposeBag)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func selectedGoodsName() -> String {
|
||||||
|
for item in itemsRelay.value {
|
||||||
|
switch item {
|
||||||
|
case .recommend(let m): if m.goods_id == selectedGoodsId { return m.goods_name }
|
||||||
|
case .normal(let m): if m.goods_id == selectedGoodsId { return m.goods_name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handlePaymentSuccess() {
|
||||||
|
UserService.userInfo().subscribe { [weak self] response in
|
||||||
|
if let model = response.model {
|
||||||
|
AppContextManager.shared.saveAccount(model)
|
||||||
|
}
|
||||||
|
self?.showPayResultPop(showCloseBtn: false,
|
||||||
|
status: true,
|
||||||
|
title: "支付成功",
|
||||||
|
message: "恭喜您!成功开通\(self?.selectedGoodsName() ?? "")",
|
||||||
|
confirmText: "确定", confirmBlock: {
|
||||||
|
AppRouter.shared.popOrDismiss()
|
||||||
|
}, cancelBlock: { })
|
||||||
|
}.disposed(by: disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupTableView() {
|
private func setupTableView() {
|
||||||
|
|
@ -179,9 +209,9 @@ class PromotionalActivitiesVC: BaseViewController {
|
||||||
WXApi.send(request)
|
WXApi.send(request)
|
||||||
}
|
}
|
||||||
else if payType == "alipay" { // 支付宝
|
else if payType == "alipay" { // 支付宝
|
||||||
if let payParam = data["payParam"] as? String, let appId = data["payParam"] as? String {
|
if let payParam = data["payParam"] as? String, let appId = data["appId"] as? String {
|
||||||
AlipaySDK.defaultService().payOrder(payParam, fromScheme: "Alipay\(appId)") { resultDic in
|
AlipaySDK.defaultService().payOrder(payParam, fromScheme: "Alipay\(appId)") { resultDic in
|
||||||
print("支付宝callback -> \(resultDic)")
|
// print("支付宝callback -> \(resultDic)")
|
||||||
guard let result = resultDic,
|
guard let result = resultDic,
|
||||||
let resultStatus = result["resultStatus"] as? String else { return }
|
let resultStatus = result["resultStatus"] as? String else { return }
|
||||||
/**
|
/**
|
||||||
|
|
@ -195,13 +225,7 @@ class PromotionalActivitiesVC: BaseViewController {
|
||||||
其它 其它支付错误。
|
其它 其它支付错误。
|
||||||
*/
|
*/
|
||||||
if resultStatus == "9000" {
|
if resultStatus == "9000" {
|
||||||
self.showPayResultPop(showCloseBtn: false,
|
self.handlePaymentSuccess()
|
||||||
status: true,
|
|
||||||
title: "支付成功",
|
|
||||||
message: "恭喜您!成功开通\("")",
|
|
||||||
confirmText: "确定", confirmBlock: {
|
|
||||||
AppRouter.shared.popOrDismiss()
|
|
||||||
}, cancelBlock: { })
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.showPayResultPop(status: false,
|
self.showPayResultPop(status: false,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,26 @@ class VipRechargeVC: BaseViewController {
|
||||||
bindViewModel()
|
bindViewModel()
|
||||||
reactiveAction()
|
reactiveAction()
|
||||||
requestRechargeInfo()
|
requestRechargeInfo()
|
||||||
|
|
||||||
|
NotificationCenter.default.rx.notification(.RequestOrderPayStatusNotification)
|
||||||
|
.subscribe(onNext: { [weak self] _ in
|
||||||
|
self?.handlePaymentSuccess()
|
||||||
|
}).disposed(by: disposeBag)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func handlePaymentSuccess() {
|
||||||
|
UserService.userInfo().subscribe { [weak self] response in
|
||||||
|
if let model = response.model {
|
||||||
|
AppContextManager.shared.saveAccount(model)
|
||||||
|
}
|
||||||
|
self?.showPayResultPop(showCloseBtn: false,
|
||||||
|
status: true,
|
||||||
|
title: "支付成功",
|
||||||
|
message: "恭喜您!成功开通\(self?.viewModel.goodsName ?? "")",
|
||||||
|
confirmText: "确定", confirmBlock: {
|
||||||
|
AppRouter.shared.popOrDismiss()
|
||||||
|
}, cancelBlock: { })
|
||||||
|
}.disposed(by: disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
|
|
@ -154,9 +174,9 @@ class VipRechargeVC: BaseViewController {
|
||||||
WXApi.send(request)
|
WXApi.send(request)
|
||||||
}
|
}
|
||||||
else if payType == "alipay" { // 支付宝
|
else if payType == "alipay" { // 支付宝
|
||||||
if let payParam = data["payParam"] as? String, let appId = data["payParam"] as? String {
|
if let payParam = data["payParam"] as? String, let appId = data["appId"] as? String {
|
||||||
AlipaySDK.defaultService().payOrder(payParam, fromScheme: "Alipay\(appId)") { resultDic in
|
AlipaySDK.defaultService().payOrder(payParam, fromScheme: "Alipay\(appId)") { resultDic in
|
||||||
print("支付宝callback -> \(resultDic)")
|
// print("支付宝callback -> \(resultDic)")
|
||||||
guard let result = resultDic,
|
guard let result = resultDic,
|
||||||
let resultStatus = result["resultStatus"] as? String else { return }
|
let resultStatus = result["resultStatus"] as? String else { return }
|
||||||
/**
|
/**
|
||||||
|
|
@ -170,13 +190,7 @@ class VipRechargeVC: BaseViewController {
|
||||||
其它 其它支付错误。
|
其它 其它支付错误。
|
||||||
*/
|
*/
|
||||||
if resultStatus == "9000" {
|
if resultStatus == "9000" {
|
||||||
self.showPayResultPop(showCloseBtn: false,
|
self.handlePaymentSuccess()
|
||||||
status: true,
|
|
||||||
title: "支付成功",
|
|
||||||
message: "恭喜您!成功开通\(self.viewModel.goodsName)",
|
|
||||||
confirmText: "确定", confirmBlock: {
|
|
||||||
AppRouter.shared.popOrDismiss()
|
|
||||||
}, cancelBlock: { })
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self.showPayResultPop(status: false,
|
self.showPayResultPop(status: false,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue