优化内购交易重试机制,增加交易重试次数记录,完善后台任务处理,更新相关API接口,调整UI组件约束,修复部分UI问题,更新本地化字符串。版本号更新至20.20.63。
This commit is contained in:
@@ -188,7 +188,6 @@
|
||||
/// @param uid 用户uid
|
||||
/// @param ticket ticket
|
||||
+ (void)checkReceipt:(HttpRequestHelperCompletion)completion chooseEnv:(NSString *)chooseEnv chargeRecordId:(NSString *)chargeRecordId transcationId:(NSString *)transcationId uid:(NSString *)uid ticket:(NSString *)ticket {
|
||||
|
||||
[self makeRequest:@"storeKitV2/verifyOrder" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, chooseEnv, chargeRecordId, transcationId, uid, ticket, nil];
|
||||
}
|
||||
|
||||
|
@@ -57,7 +57,7 @@
|
||||
[self.removeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.trailing.mas_equalTo(self.contentView).offset(-8);
|
||||
make.centerY.mas_equalTo(self.contentView);
|
||||
make.height.mas_equalTo(30);
|
||||
make.height.mas_equalTo(25);
|
||||
make.width.mas_greaterThanOrEqualTo(60);
|
||||
}];
|
||||
}
|
||||
@@ -103,11 +103,11 @@
|
||||
_removeButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_removeButton.titleLabel setFont:kFontRegular(13)];
|
||||
[_removeButton setTitle:YMLocalizedString(@"XPMineBlackListViewController1") forState:UIControlStateNormal];
|
||||
[_removeButton setTitleColor:UIColorFromRGB(0xfcc074) forState:UIControlStateNormal];
|
||||
[_removeButton setCornerRadius:15
|
||||
[_removeButton setTitleColor:UIColorFromRGB(0xff8c03) forState:UIControlStateNormal];
|
||||
[_removeButton setCornerRadius:25/2
|
||||
corners:kCALayerMaxXMaxYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner
|
||||
borderWidth:1
|
||||
borderColor:UIColorFromRGB(0xfcc074)];
|
||||
borderColor:UIColorFromRGB(0xff8c03)];
|
||||
_removeButton.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10);
|
||||
_removeButton.titleLabel.lineBreakMode = NSLineBreakByClipping;
|
||||
_removeButton.clipsToBounds = NO;
|
||||
|
@@ -6,11 +6,13 @@
|
||||
//
|
||||
|
||||
#import "IAPManager.h"
|
||||
|
||||
#import <Bugly/Bugly.h>
|
||||
#import "Api+Mine.h"
|
||||
#import "YuMi-swift.h"
|
||||
#import "RechargeStorage.h"
|
||||
|
||||
#define MAX_RETRY_COUNT 10
|
||||
|
||||
@interface IAPManager()
|
||||
|
||||
@property (nonatomic, assign) BOOL isLogin;
|
||||
@@ -28,6 +30,9 @@
|
||||
@property (nonatomic, copy) void(^failurePurchase)(NSError *error);
|
||||
@property (nonatomic, copy) void(^contactCustomerService)(NSString *uid);
|
||||
|
||||
// 记录交易重试次数
|
||||
@property (nonatomic, strong) NSMutableDictionary *retryCountMap;
|
||||
|
||||
@end
|
||||
|
||||
@implementation IAPManager
|
||||
@@ -41,6 +46,7 @@
|
||||
|
||||
proxy.recheckIndex = 0;
|
||||
proxy.recheckInterval = 1.0;
|
||||
proxy.retryCountMap = [NSMutableDictionary dictionary];
|
||||
});
|
||||
|
||||
return proxy;
|
||||
@@ -84,15 +90,27 @@
|
||||
|
||||
// 定时轮训未完成的订单并进行验单
|
||||
- (void)retryCheckAllReceipt {
|
||||
self.recheckTimer = [NSTimer scheduledTimerWithTimeInterval:self.recheckInterval
|
||||
target:self
|
||||
selector:@selector(handleRetryCheckReceipt)
|
||||
userInfo:nil
|
||||
repeats:NO];
|
||||
// 先清理旧定时器
|
||||
if (self.recheckTimer) {
|
||||
[self.recheckTimer invalidate];
|
||||
self.recheckTimer = nil;
|
||||
}
|
||||
|
||||
// 设置最大重试间隔
|
||||
NSTimeInterval interval = MIN(self.recheckInterval, 300.0);
|
||||
|
||||
// 使用传统定时器创建方式,避免在旧版iOS上的兼容性问题
|
||||
self.recheckTimer = [NSTimer scheduledTimerWithTimeInterval:interval
|
||||
target:self
|
||||
selector:@selector(handleRetryCheckReceipt)
|
||||
userInfo:nil
|
||||
repeats:NO];
|
||||
}
|
||||
|
||||
// 验单逻辑
|
||||
- (void)handleRetryCheckReceipt {
|
||||
// NSLog(@"[YuMi IAP] 用户触发补单检查 - Retry checking receipts");
|
||||
|
||||
NSArray *array = [RechargeStorage getAllReceiptsWithUid:[AccountInfoStorage instance].getUid];
|
||||
// NSLog(@" ------------.------------ 尝试:%@", array);
|
||||
@synchronized (array) {
|
||||
@@ -107,21 +125,46 @@
|
||||
if (self.recheckIndex >= array.count) {
|
||||
self.recheckIndex = 0;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// [self requestAPPOrderData:@"com.hflighting.yumi.gold.1_7000" isFroRecheck:YES];
|
||||
|
||||
#endif
|
||||
self.isProcessing = YES;
|
||||
NSDictionary *dic = [array xpSafeObjectAtIndex:self.recheckIndex];
|
||||
NSString *transactionId = dic[@"transactionId"];
|
||||
|
||||
[self _logToBugly:transactionId oID:dic[@"orderId"] status:0];
|
||||
|
||||
NSInteger retryCount = [self getRetryCountForTransaction:transactionId];
|
||||
|
||||
if (retryCount > MAX_RETRY_COUNT) {
|
||||
// 超过最大重试次数,记录并清理
|
||||
[self _logToBugly:transactionId oID:dic[@"orderId"] status:4]; // 新状态:重试次数过多
|
||||
[RechargeStorage delegateTransactionId:transactionId uid:[AccountInfoStorage instance].getUid];
|
||||
self.isProcessing = NO;
|
||||
return;
|
||||
}
|
||||
|
||||
// 增加重试计数
|
||||
[self incrementRetryCountForTransaction:transactionId];
|
||||
|
||||
@kWeakify(self);
|
||||
[self backgroundCheckReceiptWithTransactionID:transactionId
|
||||
orderID:dic[@"orderId"]
|
||||
next:^(BOOL isSuccess){
|
||||
@kStrongify(self);
|
||||
if (isSuccess) {
|
||||
[RechargeStorage delegateTransactionId:transactionId
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
self.recheckInterval = 1.0;
|
||||
self.recheckInterval = MIN(self.recheckInterval * 2, 300.0);
|
||||
|
||||
[self _logToBugly:transactionId oID:dic[@"orderId"] status:1];
|
||||
|
||||
// 成功后移除重试记录
|
||||
[self removeRetryCountForTransaction:transactionId];
|
||||
|
||||
} else {
|
||||
self.recheckInterval = self.recheckInterval * 2;
|
||||
[self _logToBugly:transactionId oID:dic[@"orderId"] status:2];
|
||||
}
|
||||
|
||||
self.recheckIndex += 1;
|
||||
@@ -134,6 +177,51 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_logToBugly:(NSString *)tid oID:(NSString *)oid status:(NSInteger)status {
|
||||
|
||||
NSMutableDictionary *logDic = [NSMutableDictionary dictionary];
|
||||
[logDic setObject:tid forKey:@"内购 transactionId"];
|
||||
[logDic setObject:oid forKey:@"内购 orderId"];
|
||||
[logDic setObject:[AccountInfoStorage instance].getUid forKey:@"内购 用户id"];
|
||||
|
||||
NSString *statusMsg = @"";
|
||||
NSInteger code = -20000;
|
||||
switch (status) {
|
||||
case 0:
|
||||
statusMsg = [NSString stringWithFormat:@"UID: %@, 尝试验单",
|
||||
[AccountInfoStorage instance].getUid];
|
||||
break;
|
||||
case 1:
|
||||
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单成功",
|
||||
[AccountInfoStorage instance].getUid];
|
||||
code = -20001;
|
||||
break;
|
||||
case 2:
|
||||
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单失败",
|
||||
[AccountInfoStorage instance].getUid];
|
||||
code = -20002;
|
||||
break;
|
||||
case 3:
|
||||
statusMsg = [NSString stringWithFormat:@"UID: %@, 验单-补单 id 异常",
|
||||
[AccountInfoStorage instance].getUid];
|
||||
code = -20002;
|
||||
break;
|
||||
case 4:
|
||||
statusMsg = [NSString stringWithFormat:@"UID: %@, 重试次数过多",
|
||||
[AccountInfoStorage instance].getUid];
|
||||
code = -20003;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
[Bugly reportError:[NSError errorWithDomain:statusMsg
|
||||
code:code
|
||||
userInfo:logDic]];
|
||||
});
|
||||
}
|
||||
|
||||
// 内购成功并通知外部
|
||||
- (void)handleSuccessPurchase:(NSString *)tID order:(NSString *)orderID {
|
||||
if (self.successPurchase) {
|
||||
@@ -312,27 +400,20 @@
|
||||
// 内购付款成功后保存收据 id 到钥匙串
|
||||
- (void)saveTransactionID {
|
||||
NSString *encodedReceipt = [self fetchEncodedReceipt];
|
||||
// 初始化字典并逐步填充
|
||||
NSMutableDictionary *receiptInfo = [NSMutableDictionary dictionary];
|
||||
|
||||
// 使用通用方法添加字典键值对,减少冗余代码
|
||||
|
||||
[self addValueIfNotNil:self.transactionID forKey:@"transactionId" toDictionary:receiptInfo];
|
||||
[self addValueIfNotNil:encodedReceipt forKey:@"receipt" toDictionary:receiptInfo];
|
||||
[self addValueIfNotNil:self.orderID forKey:@"orderId" toDictionary:receiptInfo];
|
||||
|
||||
// 如果字典为空,直接返回
|
||||
if (receiptInfo.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存数据到 RechargeStorage
|
||||
|
||||
// 添加时间戳便于后续判断过期交易
|
||||
[receiptInfo setObject:[[NSDate date] description] forKey:@"timestamp"];
|
||||
|
||||
@synchronized (self.transactionID) {
|
||||
[RechargeStorage saveTransactionId:self.transactionID
|
||||
receipt:[receiptInfo toJSONString]
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
receipt:[receiptInfo toJSONString]
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
}
|
||||
|
||||
// NSLog(@" ------------.------------ 保存账单内容:%@ ", receiptInfo);
|
||||
}
|
||||
|
||||
// 通过苹果收据与后端订单进行验单与发货
|
||||
@@ -368,31 +449,26 @@
|
||||
orderID:(NSString *)orderID
|
||||
next:(void(^)(BOOL isSuccess))next {
|
||||
|
||||
// NSLog(@" ------------.------------ 尝试后端验单:%@ | %@", tID, orderID);
|
||||
|
||||
if (![self isValidTransactionID:tID orderID:orderID]) {
|
||||
// 本地数据异常,不重试
|
||||
[self handleCheckReceiptSuccess:tID isFromRecheck:YES];
|
||||
next(NO);
|
||||
return;
|
||||
}
|
||||
// 创建后台任务标识
|
||||
UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"VerifyReceipt"
|
||||
expirationHandler:^{
|
||||
// 超时处理
|
||||
if (next) {
|
||||
next(NO);
|
||||
}
|
||||
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
|
||||
}];
|
||||
|
||||
// 原验证代码...
|
||||
|
||||
// 完成后务必结束后台任务
|
||||
@kWeakify(self);
|
||||
[Api checkReceipt:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
|
||||
@kStrongify(self);
|
||||
if (code == 200) {
|
||||
[self handleCheckReceiptSuccess:tID isFromRecheck:YES];
|
||||
} else if (code == 1701) {
|
||||
// 交易已完成,無需重複請求
|
||||
[self handleCheckReceiptSuccess:tID isFromRecheck:YES];
|
||||
}
|
||||
// 原有验证代码...
|
||||
|
||||
// NSLog(@" ------------.------------ 尝试后端验单结果:%ld, %@ ", (long)code, msg);
|
||||
|
||||
if (next) {
|
||||
next(code == 200 || code == 1701);
|
||||
}
|
||||
// 结束后台任务
|
||||
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
|
||||
}
|
||||
chooseEnv:@"true"
|
||||
chargeRecordId:orderID
|
||||
@@ -414,6 +490,8 @@
|
||||
// 流程完成,移除本地缓存账单
|
||||
[RechargeStorage delegateTransactionId:tID
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
// 成功后移除重试记录
|
||||
[self removeRetryCountForTransaction:tID];
|
||||
} else {
|
||||
// 出现异常
|
||||
// NSLog(@" ------------.------------ apple 验单成功:%@ ",error);
|
||||
@@ -421,6 +499,8 @@
|
||||
// 该订单在 appstore 已无法找到,不必再重试
|
||||
[RechargeStorage delegateTransactionId:tID
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
// 清理不存在的交易记录
|
||||
[self removeRetryCountForTransaction:tID];
|
||||
} else {
|
||||
[self retryCheckAllReceipt];
|
||||
}
|
||||
@@ -443,4 +523,75 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 添加 dealloc 方法确保定时器释放
|
||||
- (void)dealloc {
|
||||
if (self.recheckTimer) {
|
||||
[self.recheckTimer invalidate];
|
||||
self.recheckTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// 在应用进入后台时暂停定时器
|
||||
- (void)applicationDidEnterBackground {
|
||||
if (self.recheckTimer) {
|
||||
[self.recheckTimer invalidate];
|
||||
self.recheckTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
// 在应用恢复活动时重新启动定时器
|
||||
- (void)applicationWillEnterForeground {
|
||||
if (self.isLogin) {
|
||||
[self retryCheckAllReceipt];
|
||||
}
|
||||
}
|
||||
|
||||
// 清理长时间未处理的交易记录
|
||||
- (void)cleanupStaleTransactions {
|
||||
NSArray *receipts = [RechargeStorage getAllReceiptsWithUid:[AccountInfoStorage instance].getUid];
|
||||
NSDate *now = [NSDate date];
|
||||
|
||||
for (NSDictionary *receipt in receipts) {
|
||||
// 检查交易时间,如果超过7天还未成功,则清理
|
||||
NSString *timestamp = receipt[@"timestamp"];
|
||||
if (timestamp) {
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss Z"]; // 根据实际时间格式调整
|
||||
NSDate *transactionDate = [dateFormatter dateFromString:timestamp];
|
||||
|
||||
if (transactionDate && [now timeIntervalSinceDate:transactionDate] > 70 * 24 * 60 * 60) {
|
||||
NSString *tID = receipt[@"transactionId"];
|
||||
[RechargeStorage delegateTransactionId:tID uid:[AccountInfoStorage instance].getUid];
|
||||
[self _logToBugly:tID oID:receipt[@"orderId"] status:5]; // 新状态:过期清理
|
||||
|
||||
// 清理过期交易的重试记录
|
||||
[self removeRetryCountForTransaction:tID];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取交易的重试次数
|
||||
- (NSInteger)getRetryCountForTransaction:(NSString *)transactionId {
|
||||
NSNumber *countNumber = self.retryCountMap[transactionId];
|
||||
return countNumber ? [countNumber integerValue] : 0;
|
||||
}
|
||||
|
||||
// 增加交易的重试次数
|
||||
- (void)incrementRetryCountForTransaction:(NSString *)transactionId {
|
||||
NSInteger currentCount = [self getRetryCountForTransaction:transactionId];
|
||||
self.retryCountMap[transactionId] = @(currentCount + 1);
|
||||
}
|
||||
|
||||
// 移除交易的重试记录
|
||||
- (void)removeRetryCountForTransaction:(NSString *)transactionId {
|
||||
[self.retryCountMap removeObjectForKey:transactionId];
|
||||
}
|
||||
|
||||
// 清理所有重试记录
|
||||
- (void)cleanAllRetryCount {
|
||||
[self.retryCountMap removeAllObjects];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
@@ -75,6 +75,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// 删除活动
|
||||
+ (void)usereventDel:(HttpRequestHelperCompletion)complection eventId:(NSNumber *)eventId;
|
||||
|
||||
+ (void)homeBanner:(HttpRequestHelperCompletion)complection uid:(NSString *)uid type:(NSString *)type activityShow:(NSNumber *)activityShow;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -83,4 +83,8 @@
|
||||
completion:complection, __FUNCTION__, eventId, nil];
|
||||
}
|
||||
|
||||
+ (void)homeBanner:(HttpRequestHelperCompletion)complection uid:(NSString *)uid type:(NSString *)type activityShow:(NSNumber *)activityShow {
|
||||
[self makeRequest:@"home/banner" method:HttpRequestHelperMethodGET completion:complection, __FUNCTION__, uid, type, activityShow, nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -41,12 +41,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)deleteEventSuccess:(NSInteger)eventId;
|
||||
- (void)deleteEventFailure:(NSString *)msg;
|
||||
|
||||
- (void)officialEventListSuccess:(EventRoomListModel *)listModel;
|
||||
- (void)officialEventListFailure:(NSString *)msg;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@interface CreateEventPresenter : BaseMvpPresenter
|
||||
|
||||
- (void)loadConfig;
|
||||
|
||||
- (void)loadOfficialEvents;
|
||||
- (void)loadEventSquare:(NSInteger)page;
|
||||
- (void)loadMyCreateEvents:(NSInteger)page;
|
||||
- (void)loadMySubEvents:(NSInteger)page;
|
||||
|
@@ -7,7 +7,6 @@
|
||||
|
||||
#import "CreateEventPresenter.h"
|
||||
#import "Api+EventCenter.h"
|
||||
|
||||
#import <ReactiveObjC/ReactiveObjC.h>
|
||||
|
||||
@interface CreateEventPresenter()
|
||||
@@ -30,6 +29,19 @@
|
||||
uid:[AccountInfoStorage instance].getUid];
|
||||
}
|
||||
|
||||
- (void)loadOfficialEvents {
|
||||
// TODO: 补充官方活动数据 / 调整创建活动时,选择开始时间的 bug
|
||||
[Api homeBanner:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
|
||||
if ([[self getView] respondsToSelector:@selector(officialEventListSuccess:)]) {
|
||||
[[self getView] officialEventListSuccess:[EventConfigModel modelWithJSON:data.data]];
|
||||
}
|
||||
} fail:^(NSInteger code, NSString * _Nullable msg) {
|
||||
if ([[self getView] respondsToSelector:@selector(officialEventListFailure:)]) {
|
||||
[[self getView] officialEventListFailure:msg];
|
||||
}
|
||||
} showLoading:YES errorToast:YES] uid:[AccountInfoStorage instance].getUid type:@"1" activityShow:@(1)];
|
||||
}
|
||||
|
||||
- (void)loadEventSquare:(NSInteger)page {
|
||||
[Api usereventSquare:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
|
||||
if ([[self getView] respondsToSelector:@selector(eventSquareListSuccess:)]) {
|
||||
|
@@ -345,7 +345,7 @@
|
||||
NetImageConfig *config = [[NetImageConfig alloc] init];
|
||||
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
|
||||
_avatarImageView = [[NetImageView alloc] initWithConfig:config];
|
||||
[_avatarImageView setCornerRadius:12
|
||||
[_avatarImageView setCornerRadius:35/2
|
||||
corners:kCALayerMaxXMaxYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner
|
||||
borderWidth:1
|
||||
borderColor:[UIColor whiteColor]];
|
||||
@@ -422,8 +422,7 @@
|
||||
|
||||
- (UIView *)blackMask {
|
||||
UIView *v = [[UIView alloc] init];
|
||||
v.backgroundColor = [UIColor colorWithWhite:0 alpha:0.6];
|
||||
// [v setCornerRadius:8];
|
||||
v.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@@ -295,11 +295,12 @@ static const CGFloat kSectionSpacing = 20.0;
|
||||
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
|
||||
imagePickerVc.allowCrop = YES;
|
||||
|
||||
// 获取eventBannerImageView的实际尺寸比例
|
||||
CGFloat viewWidth = self.view.frame.size.width - (kHorizontalPadding * 2 - 2);
|
||||
CGFloat viewHeight = kGetScaleWidth(118);
|
||||
CGFloat cropWidth = MIN(viewWidth, KScreenWidth);
|
||||
CGFloat cropHeight = (viewHeight / viewWidth) * cropWidth;
|
||||
// 调整裁剪比例为 690:236
|
||||
CGFloat aspectRatio = 690.0 / 236.0; // 约为2.92:1
|
||||
|
||||
// 计算裁剪框宽度,限制在屏幕宽度内
|
||||
CGFloat cropWidth = MIN(self.view.frame.size.width - (kHorizontalPadding * 2 - 2), KScreenWidth);
|
||||
CGFloat cropHeight = cropWidth / aspectRatio;
|
||||
|
||||
// 设置裁剪框的尺寸
|
||||
imagePickerVc.cropRect = CGRectMake((KScreenWidth-cropWidth)/2, (KScreenHeight - cropHeight) / 2, cropWidth, cropHeight);
|
||||
@@ -392,6 +393,21 @@ static const CGFloat kSectionSpacing = 20.0;
|
||||
notifyFans:notifyFans];
|
||||
}];
|
||||
} cancelHandler:^{ }];
|
||||
} else {
|
||||
@kWeakify(self);
|
||||
[self uploadCover:bannerImage
|
||||
finish:^(NSString *path) {
|
||||
@kStrongify(self);
|
||||
[self.presenter createEventWithTitle:title
|
||||
image:path
|
||||
uploadToHome:uploadToHomepage
|
||||
startTime:startTime
|
||||
duration:self.durationMinutes
|
||||
content:content
|
||||
gold:uploadToHomepage ? self.configModel.goldNum : 0
|
||||
roomUid:self.selectRoomModel.roomUid
|
||||
notifyFans:notifyFans];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,8 +524,9 @@ static const CGFloat kSectionSpacing = 20.0;
|
||||
UIImage *selectedImage = info[UIImagePickerControllerOriginalImage];
|
||||
if (selectedImage) {
|
||||
// 对于iOS 14以下版本,选择图片后手动裁剪
|
||||
CGFloat aspectRatio = 690.0 / 236.0; // 约为2.92:1
|
||||
CGFloat viewWidth = self.view.frame.size.width - (kHorizontalPadding * 2 - 2);
|
||||
CGFloat viewHeight = kGetScaleWidth(118);
|
||||
CGFloat viewHeight = viewWidth / aspectRatio;
|
||||
CGSize cropSize = CGSizeMake(viewWidth, viewHeight);
|
||||
|
||||
UIImage *croppedImage = [selectedImage cutImage:cropSize];
|
||||
@@ -587,7 +604,9 @@ static const CGFloat kSectionSpacing = 20.0;
|
||||
[self.eventBannerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.eventBannerLabel.mas_bottom).offset(kVerticalPadding);
|
||||
make.leading.trailing.equalTo(self.contentView).inset(kHorizontalPadding-1);
|
||||
make.height.mas_equalTo(kGetScaleWidth(118)); // Adjust height as needed
|
||||
|
||||
// 设置高度为宽度除以690:236的比例
|
||||
make.height.equalTo(self.eventBannerImageView.mas_width).multipliedBy(236.0/690.0);
|
||||
}];
|
||||
[self.eventBannerCamearImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.bottom.trailing.equalTo(self.eventBannerImageView);
|
||||
|
@@ -179,11 +179,11 @@ static UIEdgeInsets kOfficialTableViewContentInset(void) {
|
||||
#pragma mark - Setup Data
|
||||
- (void)setOfficialEventModels:(NSArray<HomeBannerInfoModel *> *)officialEventModels {
|
||||
_officialDatasource = officialEventModels.mutableCopy;
|
||||
#if DEBUG
|
||||
#else
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"activityShow == %@", @(1)];
|
||||
[_officialDatasource filterUsingPredicate:predicate];
|
||||
#endif
|
||||
//#if DEBUG
|
||||
//#else
|
||||
// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"activityShow == %@", @(1)];
|
||||
// [_officialDatasource filterUsingPredicate:predicate];
|
||||
//#endif
|
||||
|
||||
// 处理空数据状态
|
||||
if (_officialDatasource.count == 0) {
|
||||
@@ -323,7 +323,7 @@ static UIEdgeInsets kOfficialTableViewContentInset(void) {
|
||||
}];
|
||||
|
||||
if (section == 0) {
|
||||
UIImageView *arrow = [[UIImageView alloc] initWithImage:kImage(@"event_arrow_black")];
|
||||
UIImageView *arrow = [[UIImageView alloc] initWithImage:[kImage(@"event_arrow_black") ms_SetImageForRTL]];
|
||||
arrow.userInteractionEnabled = YES;
|
||||
[v addSubview:arrow];
|
||||
[arrow mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
@@ -619,9 +619,12 @@ static UIEdgeInsets kOfficialTableViewContentInset(void) {
|
||||
}
|
||||
|
||||
- (void)eventSubActionSuccess:(BOOL)isSub eventId:(NSInteger)eventId {
|
||||
NSInteger count = 0;
|
||||
if (isSub) {
|
||||
count += 1;
|
||||
[XNDJTDDLoadingTool showSuccessWithMessage:YMLocalizedString(@"20.20.59_text_35")];
|
||||
} else {
|
||||
count -= 1;
|
||||
[XNDJTDDLoadingTool showSuccessWithMessage:YMLocalizedString(@"20.20.59_text_36")];
|
||||
}
|
||||
|
||||
@@ -630,6 +633,7 @@ static UIEdgeInsets kOfficialTableViewContentInset(void) {
|
||||
for (EventItemModel *m in self.eventSquareDatasource) {
|
||||
if (m.id == eventId) {
|
||||
m.subStatus = isSub;
|
||||
m.subNum += count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -639,12 +643,14 @@ static UIEdgeInsets kOfficialTableViewContentInset(void) {
|
||||
for (EventItemModel *m in self.mySubEventDatasource) {
|
||||
if (m.id == eventId) {
|
||||
m.subStatus = isSub;
|
||||
m.subNum += count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (EventItemModel *m in self.myCreateEventDatasource) {
|
||||
if (m.id == eventId) {
|
||||
m.subStatus = isSub;
|
||||
m.subNum += count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -129,15 +129,19 @@
|
||||
}
|
||||
|
||||
- (void)eventSubActionSuccess:(BOOL)isSub eventId:(NSInteger)eventId {
|
||||
NSInteger count = 0;
|
||||
if (isSub) {
|
||||
count += 1;
|
||||
[XNDJTDDLoadingTool showSuccessWithMessage:YMLocalizedString(@"20.20.59_text_35")];
|
||||
} else {
|
||||
count -= 1;
|
||||
[XNDJTDDLoadingTool showSuccessWithMessage:YMLocalizedString(@"20.20.59_text_36")];
|
||||
}
|
||||
|
||||
for (EventItemModel *m in self.datasource) {
|
||||
if (m.id == eventId) {
|
||||
m.subStatus = isSub;
|
||||
m.subNum += count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -60,6 +60,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// @param completion 完成
|
||||
/// @param roomUid 房主的uid
|
||||
+ (void)checkManageNum:(HttpRequestHelperCompletion)completion roomUid:(NSString *)roomUid;
|
||||
|
||||
/// 添加移除管理员(后段管理的用户关系)
|
||||
/// Long roomUid,
|
||||
/// Long uid,
|
||||
/// Integer opt, //1添加,2移除
|
||||
+ (void)updateRoleToServer:(HttpRequestHelperCompletion)completion roomUid:(NSString *)roomUid uid:(NSString *)uid opt:(NSString *)opt ;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -63,4 +63,9 @@
|
||||
[self makeRequest:@"room/checkManageNum" method:HttpRequestHelperMethodPOST completion:completion, __FUNCTION__, roomUid, nil];
|
||||
}
|
||||
|
||||
+ (void)updateRoleToServer:(HttpRequestHelperCompletion)completion roomUid:(NSString *)roomUid uid:(NSString *)uid opt:(NSString *)opt {
|
||||
[self makeRequest:@"roomrole/manageOpt" method:HttpRequestHelperMethodPOST completion:completion,
|
||||
__FUNCTION__, roomUid, uid, opt, nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// @param targetUid 目标用户的id
|
||||
/// @param roomId 房间的id
|
||||
/// @param enable YES设置 NO取消
|
||||
- (void)makeUserManager:(NSString *)targetUid roomId:(NSString *)roomId enable:(BOOL)enable;
|
||||
- (void)makeUserManager:(NSString *)targetUid roomId:(NSString *)roomId roomUid:(NSString *)roomUid enable:(BOOL)enable;
|
||||
|
||||
/// 踢出房间
|
||||
/// @param targetUid 用户的uid
|
||||
|
@@ -527,7 +527,7 @@
|
||||
/// @param targetUid 目标用户的id
|
||||
/// @param roomId 房间的id
|
||||
/// @param enable YES设置 NO取消
|
||||
- (void)makeUserManager:(NSString *)targetUid roomId:(NSString *)roomId enable:(BOOL)enable{
|
||||
- (void)makeUserManager:(NSString *)targetUid roomId:(NSString *)roomId roomUid:(NSString *)roomUid enable:(BOOL)enable{
|
||||
NIMChatroomMemberUpdateRequest *request = [[NIMChatroomMemberUpdateRequest alloc]init];
|
||||
request.roomId = roomId;
|
||||
request.userId = targetUid;
|
||||
@@ -537,6 +537,10 @@
|
||||
@kStrongify(self);
|
||||
if (error == nil) {
|
||||
self.managerItem.isSelect = enable;
|
||||
[Api updateRoleToServer:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
|
||||
// 不用处理返回
|
||||
NSLog(@"%@", data);
|
||||
}] roomUid:roomUid uid:targetUid opt:enable ? @"1" : @"2"];
|
||||
}
|
||||
[[self getView] markUserManagerFinish:self.managerItem error:error];
|
||||
}];
|
||||
|
@@ -1228,7 +1228,7 @@
|
||||
if ([self isSuperUser]) {
|
||||
[self.presenter superAdminHandleUser:self.cardInfo.uid opt:@"1" roomUid:roomUid isSet:!item.isSelect];
|
||||
} else {
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId enable:!item.isSelect];
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId roomUid:roomUid enable:!item.isSelect];
|
||||
}
|
||||
} else {
|
||||
@kWeakify(self);
|
||||
@@ -1237,7 +1237,7 @@
|
||||
if ([self isSuperUser]) {
|
||||
[self.presenter superAdminHandleUser:self.cardInfo.uid opt:@"1" roomUid:roomUid isSet:!item.isSelect];
|
||||
} else {
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId enable:!item.isSelect];
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId roomUid:roomUid enable:!item.isSelect];
|
||||
}
|
||||
} failure:^(NSError * _Nonnull error) {
|
||||
if (error.code == 20504) { // 管理员数量已达上限
|
||||
|
@@ -1114,7 +1114,7 @@
|
||||
if (meIsSuperAdmin) {
|
||||
[self.presenter superAdminHandleUser:self.cardInfo.uid opt:@"1" roomUid:roomUid isSet:!model.isSelect];
|
||||
} else {
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId enable:!model.isSelect];
|
||||
[self.presenter makeUserManager:self.cardInfo.uid roomId:roomId roomUid:roomUid enable:!model.isSelect];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@@ -75,6 +75,7 @@ NSString * const kJPClose = @"newTppClose";
|
||||
|
||||
- (void)dealloc {
|
||||
[self cleanupWebView];
|
||||
[self hideHUD];
|
||||
[self.loadingTimer invalidate];
|
||||
self.loadingTimer = nil;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@@ -277,7 +278,7 @@ NSString * const kJPClose = @"newTppClose";
|
||||
}
|
||||
|
||||
- (BOOL)isValidGameURL:(NSString *)urlString {
|
||||
if (!urlString || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) {
|
||||
if ([NSString isEmpty:urlString]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
@@ -4178,7 +4178,7 @@ ineHeadView12" = "الحمل";
|
||||
"20.20.59_text_7" = " شارك";
|
||||
"20.20.59_text_8" = "إنشاء الحدث";
|
||||
"20.20.59_text_9" = "عنوان الحدث";
|
||||
"20.20.59_text_10" = "بنر الفعالية";
|
||||
"20.20.59_text_10" = "بنر الفعالية(Best size:690*236)";
|
||||
"20.20.59_text_11" = "رفع بنر إلى الصفحة الرئيسية(%@التكاليف )";
|
||||
"20.20.59_text_12" = "نعم";
|
||||
"20.20.59_text_13" = "لا ";
|
||||
|
@@ -3963,7 +3963,7 @@
|
||||
"20.20.59_text_7" = " Participate";
|
||||
"20.20.59_text_8" = "Create Event";
|
||||
"20.20.59_text_9" = "Event Title";
|
||||
"20.20.59_text_10" = "Event Banner";
|
||||
"20.20.59_text_10" = "Event Banner(Best size:690*236)";
|
||||
"20.20.59_text_11" = "Upload Banner to Homepage(Costs %@)";
|
||||
"20.20.59_text_12" = "YES";
|
||||
"20.20.59_text_13" = "NO";
|
||||
|
@@ -3756,7 +3756,7 @@
|
||||
"20.20.59_text_7" = " Katılmak";
|
||||
"20.20.59_text_8" = "Etkinlik Oluştur";
|
||||
"20.20.59_text_9" = "Etkinlik Başlığı";
|
||||
"20.20.59_text_10" = "Etkinlik Afişi";
|
||||
"20.20.59_text_10" = "Etkinlik Afişi(Best size:690*236)";
|
||||
"20.20.59_text_11" = "Ana Sayfaya Banner Yükleyin(Maliyet %@)";
|
||||
"20.20.59_text_12" = "Evet";
|
||||
"20.20.59_text_13" = "Hayır";
|
||||
|
@@ -3628,7 +3628,7 @@
|
||||
"20.20.59_text_7" = " 參與活動";
|
||||
"20.20.59_text_8" = "建立活動";
|
||||
"20.20.59_text_9" = "活動標題";
|
||||
"20.20.59_text_10" = "活動橫幅";
|
||||
"20.20.59_text_10" = "活動橫幅(Best size:690*236)";
|
||||
"20.20.59_text_11" = "上傳橫幅至首頁(成本 %@)";
|
||||
"20.20.59_text_12" = "有";
|
||||
"20.20.59_text_13" = "無";
|
||||
|
Reference in New Issue
Block a user