新增 CP SVGA 逻辑迁移测试报告,详细记录了在 MicMidpointRectManager 中新增的 CP 业务逻辑方法及其在 XPRoomViewController 中的简化调用。修复了编译错误,优化了代码结构,提升了可维护性和可测试性。同时,更新了 MicMidpointRectManager 的头文件,添加了新方法的声明,确保代码一致性和清晰性。
This commit is contained in:
@@ -137,6 +137,7 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
||||
make.centerX.mas_equalTo(self.view);
|
||||
make.bottom.mas_equalTo(self.view).offset(-44);
|
||||
make.width.mas_lessThanOrEqualTo(self.view).offset(-32);
|
||||
make.height.mas_equalTo(60);
|
||||
}];
|
||||
|
||||
[self.agreeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
@@ -189,6 +190,7 @@ typedef NS_ENUM(NSUInteger, LoginType) {
|
||||
[button setCornerRadius:23];
|
||||
[button setBackgroundColor:[UIColor whiteColor]];
|
||||
[button.titleLabel setFont:kFontSemibold(14)];
|
||||
[button.titleLabel setAdjustsFontSizeToFitWidth:YES];
|
||||
[button setTitleColor:UIColorFromRGB(0x313131) forState:UIControlStateNormal];
|
||||
switch (type) {
|
||||
case LoginType_ID:{
|
||||
|
@@ -87,7 +87,7 @@
|
||||
|
||||
[self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.myGoldView.mas_bottom).offset(4);
|
||||
make.leading.mas_equalTo(self.myGoldView).offset(15);
|
||||
make.leading.trailing.mas_equalTo(self.myGoldView).inset(15);
|
||||
}];
|
||||
}
|
||||
/// 返回
|
||||
@@ -98,6 +98,8 @@
|
||||
_model = model;
|
||||
_myGoldView.model = _model;
|
||||
_myDiamondsView.model = _model;
|
||||
self.descLabel.text = [NSString stringWithFormat:YMLocalizedString(@"20.20.51_text_29"),
|
||||
@(model.minDiamonds)];
|
||||
}
|
||||
-(void)confirmAction{
|
||||
if( self.model.diamonds < self.diamondNum.doubleValue){
|
||||
@@ -149,7 +151,8 @@
|
||||
|
||||
- (UILabel *)descLabel {
|
||||
if (!_descLabel) {
|
||||
_descLabel = [UILabel labelInitWithText:YMLocalizedString(@"20.20.51_text_29") font:kFontSemibold(14) textColor:[UIColor lightGrayColor]];
|
||||
_descLabel = [UILabel labelInitWithText:@"" font:kFontSemibold(14) textColor:[UIColor lightGrayColor]];
|
||||
_descLabel.adjustsFontSizeToFitWidth = YES;
|
||||
}
|
||||
return _descLabel;
|
||||
}
|
||||
@@ -263,7 +266,7 @@
|
||||
}
|
||||
NSInteger count = textField.text.integerValue;
|
||||
NSString *diamondNum = [NSString stringWithFormat:@"%.0f",floorf(count * _model.rate)];
|
||||
if (count < 1000 || count % 1000 != 0) {
|
||||
if (count < self.model.minDiamonds || count % self.model.minDiamonds != 0) {
|
||||
diamondNum = @"0";
|
||||
}
|
||||
if(self.inputCounthandle){
|
||||
|
@@ -11,6 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class MicMidpointRectManager;
|
||||
@class UIView;
|
||||
@class MicroQueueModel;
|
||||
@class MicCpInfoModel;
|
||||
@class UserInfoModel;
|
||||
|
||||
@protocol MicMidpointRectManagerDelegate <NSObject>
|
||||
|
||||
@@ -103,6 +106,58 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
stageView:(id)stageView
|
||||
micCount:(NSInteger)micCount;
|
||||
|
||||
#pragma mark - CP Business Logic Methods
|
||||
|
||||
/// 处理麦位变化相关的CP逻辑
|
||||
- (void)handleMicChangeForCPWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
currentUserUid:(NSInteger)currentUserUid
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 处理CP绑定或升级消息
|
||||
- (void)handleCPBindingOrUpgradeMessageWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue;
|
||||
|
||||
/// 处理麦位关系CP消息
|
||||
- (void)handleMicRelationshipCPMessage:(NSArray<MicCpInfoModel *> *)cpList;
|
||||
|
||||
/// 处理其他用户mic变化
|
||||
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo
|
||||
changeType:(NSInteger)changeType
|
||||
stageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 处理用户切换mic场景,确保所有CP SVGA状态正确更新
|
||||
- (void)handleMicSwitchScenarioIfNeededWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
currentUserUid:(NSInteger)currentUserUid
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 处理下麦事件
|
||||
- (void)handleDownMicEventIfNeededWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 更新CP列表缓存并重绘
|
||||
- (void)updateCpListCacheAndRedraw:(NSArray<MicCpInfoModel *> *)cpList
|
||||
stageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 绘制社交舞台中点矩形
|
||||
- (void)drawSocialStageMidpointRectsWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
roomType:(NSInteger)roomType;
|
||||
|
||||
/// 移除指定用户的CP数据
|
||||
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@@ -430,6 +430,262 @@
|
||||
NSLog(@"🔧 下麦事件处理完成");
|
||||
}
|
||||
|
||||
#pragma mark - CP Business Logic Methods
|
||||
|
||||
/// 处理麦位变化相关的CP逻辑
|
||||
- (void)handleMicChangeForCPWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
currentUserUid:(NSInteger)currentUserUid
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 处理麦位变化相关的CP逻辑");
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
// 更新麦位快照
|
||||
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
|
||||
|
||||
// 检测下麦用户并处理CP关系缓存
|
||||
[self handleDownMicEventIfNeededWithStageView:stageView micCount:micCount queue:queue roomType:roomType];
|
||||
|
||||
// 处理用户切换mic场景,确保所有CP SVGA状态正确更新
|
||||
[self handleMicSwitchScenarioIfNeededWithStageView:stageView micCount:micCount queue:queue currentUserUid:currentUserUid roomType:roomType];
|
||||
|
||||
NSLog(@"🔧 [Manager] 麦位变化CP逻辑处理完成");
|
||||
}
|
||||
|
||||
/// 处理CP绑定或升级消息
|
||||
- (void)handleCPBindingOrUpgradeMessageWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSLog(@"🔧 [Manager] 处理CP绑定或升级消息");
|
||||
|
||||
if (!queue) {
|
||||
NSLog(@"⚠️ [Manager] 无法获取当前麦位队列,跳过CP绑定/升级处理");
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"🔧 [Manager] CP绑定/升级消息处理完成");
|
||||
}
|
||||
|
||||
/// 处理麦位关系CP消息
|
||||
- (void)handleMicRelationshipCPMessage:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
NSLog(@"🔧 [Manager] 处理麦位关系CP消息:接收到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
|
||||
if (!cpList || cpList.count == 0) {
|
||||
NSLog(@"⚠️ [Manager] CP数据为空,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新CP列表缓存
|
||||
[self setCpListCache:cpList];
|
||||
|
||||
NSLog(@"🔧 [Manager] 麦位关系CP消息处理完成");
|
||||
}
|
||||
|
||||
/// 处理其他用户mic变化
|
||||
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo
|
||||
changeType:(NSInteger)changeType
|
||||
stageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 处理其他用户mic变化:用户 %ld, 变化类型 %ld", (long)userInfo.uid, (long)changeType);
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
NSInteger userUid = userInfo.uid;
|
||||
|
||||
if (changeType == 2) { // 其他用户下麦
|
||||
// 更新快照
|
||||
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
|
||||
|
||||
// 直接移除下麦用户的CP数据
|
||||
NSArray<NSNumber *> *removedUids = @[@(userUid)];
|
||||
[self removeCpEntriesForUids:removedUids];
|
||||
[self removeMidpointRectsForUids:removedUids];
|
||||
|
||||
NSLog(@"🔧 [Manager] 其他用户下麦处理完成");
|
||||
|
||||
} else if (changeType == 1) { // 其他用户上麦
|
||||
// 更新快照
|
||||
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
|
||||
|
||||
NSLog(@"🔧 [Manager] 其他用户上麦处理完成");
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理用户切换mic场景,确保所有CP SVGA状态正确更新
|
||||
- (void)handleMicSwitchScenarioIfNeededWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
currentUserUid:(NSInteger)currentUserUid
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 处理用户切换mic场景");
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
// 检查是否有用户切换mic
|
||||
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges = [self diffMicChangeWithStageView:stageView micCount:micCount];
|
||||
NSArray<NSNumber *> *addedUids = micChanges[@"added"];
|
||||
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
|
||||
|
||||
if (addedUids.count > 0 || removedUids.count > 0) {
|
||||
NSLog(@"🔧 [Manager] 检测到麦位变化:上麦 %lu 人,下麦 %lu 人", (unsigned long)addedUids.count, (unsigned long)removedUids.count);
|
||||
|
||||
// 只清除当前用户相关的CP数据,保护其他用户的CP SVGA
|
||||
NSArray<NSNumber *> *currentUserUids = @[@(currentUserUid)];
|
||||
|
||||
// 1. 只清除当前用户相关的CP数据
|
||||
[self removeCpEntriesForUids:currentUserUids];
|
||||
[self removeMidpointRectsForUids:currentUserUids];
|
||||
|
||||
// 2. 重新构建麦位快照
|
||||
[self rebuildMicSnapshotWithStageView:stageView micCount:micCount];
|
||||
|
||||
NSLog(@"🔧 [Manager] 用户切换mic场景处理完成");
|
||||
} else {
|
||||
NSLog(@"🔧 [Manager] 没有检测到麦位变化,跳过处理");
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理下麦事件
|
||||
- (void)handleDownMicEventIfNeededWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
queue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 处理下麦事件");
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
// 使用 MicMidpointRectManager 检测麦位变化
|
||||
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges = [self diffMicChangeWithStageView:stageView micCount:micCount];
|
||||
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
|
||||
|
||||
if (removedUids && removedUids.count > 0) {
|
||||
NSLog(@"🔧 [Manager] 检测到下麦用户:%@", removedUids);
|
||||
|
||||
// 直接移除下麦用户的CP数据
|
||||
[self removeCpEntriesForUids:removedUids];
|
||||
[self removeMidpointRectsForUids:removedUids];
|
||||
|
||||
NSLog(@"🔧 [Manager] 下麦事件处理完成");
|
||||
} else {
|
||||
NSLog(@"🔧 [Manager] 没有检测到下麦用户,跳过处理");
|
||||
}
|
||||
}
|
||||
|
||||
/// 更新CP列表缓存并重绘
|
||||
- (void)updateCpListCacheAndRedraw:(NSArray<MicCpInfoModel *> *)cpList
|
||||
stageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 更新CP列表缓存并重绘:接收到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
// 更新CP列表缓存
|
||||
[self setCpListCache:cpList];
|
||||
|
||||
// 重绘社交舞台中点矩形
|
||||
[self drawSocialStageMidpointRectsWithStageView:stageView micCount:micCount roomType:roomType];
|
||||
|
||||
NSLog(@"🔧 [Manager] CP列表缓存更新和重绘完成");
|
||||
}
|
||||
|
||||
/// 绘制社交舞台中点矩形
|
||||
- (void)drawSocialStageMidpointRectsWithStageView:(id)stageView
|
||||
micCount:(NSInteger)micCount
|
||||
roomType:(NSInteger)roomType {
|
||||
NSLog(@"🔧 [Manager] 绘制社交舞台中点矩形:麦位总数 %ld", (long)micCount);
|
||||
|
||||
// 设置房间类型
|
||||
self.roomType = roomType;
|
||||
|
||||
// 移除旧的调试矩形
|
||||
[self removeAllMidpointRects];
|
||||
|
||||
if (micCount < 2) {
|
||||
NSLog(@"🔧 [Manager] 麦位数量不足,跳过绘制");
|
||||
return;
|
||||
}
|
||||
|
||||
// 遍历所有相邻的麦位对
|
||||
for (NSInteger i = 0; i < micCount - 1; i++) {
|
||||
NSInteger firstIndex = i;
|
||||
NSInteger secondIndex = i + 1;
|
||||
|
||||
// 获取两个麦位的视图
|
||||
UIView<MicroViewProtocol> *firstView = [stageView findMicroViewByIndex:firstIndex];
|
||||
UIView<MicroViewProtocol> *secondView = [stageView findMicroViewByIndex:secondIndex];
|
||||
|
||||
if (!firstView || !secondView) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取两个麦位的用户信息
|
||||
UserInfoModel *firstUser = [firstView getUser];
|
||||
UserInfoModel *secondUser = [secondView getUser];
|
||||
|
||||
if (!firstUser || !secondUser || firstUser.uid <= 0 || secondUser.uid <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 计算中点矩形的位置和大小
|
||||
CGRect firstFrame = firstView.frame;
|
||||
CGRect secondFrame = secondView.frame;
|
||||
|
||||
CGFloat midX = (firstFrame.origin.x + firstFrame.size.width + secondFrame.origin.x) / 2.0;
|
||||
CGFloat midY = (firstFrame.origin.y + secondFrame.origin.y) / 2.0;
|
||||
CGFloat width = kGetScaleWidth(75);
|
||||
CGFloat height = width;
|
||||
|
||||
CGRect rect = CGRectMake(midX - width/2, midY - height/4, width, height);
|
||||
|
||||
// 创建关系视图
|
||||
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
|
||||
micRelationshipView.backgroundColor = [UIColor clearColor];
|
||||
micRelationshipView.userInteractionEnabled = NO;
|
||||
micRelationshipView.tag = 56002;
|
||||
|
||||
// 添加关系视图到容器
|
||||
[self.containerView addSubview:micRelationshipView];
|
||||
[self.midpointRects addObject:micRelationshipView];
|
||||
|
||||
// 添加关系并播放SVGA
|
||||
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
|
||||
[self addRelationshipAtFrame:rect
|
||||
micPairText:micPairText
|
||||
leftUid:firstUser.uid
|
||||
rightUid:secondUser.uid
|
||||
cpList:self.cachedCpListInternal ?: @[]];
|
||||
}
|
||||
|
||||
NSLog(@"🔧 [Manager] 社交舞台中点矩形绘制完成");
|
||||
}
|
||||
|
||||
/// 移除指定用户的CP数据
|
||||
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids {
|
||||
NSLog(@"🔧 [Manager] 移除CP数据:UIDs %@", uids);
|
||||
|
||||
if (uids.count == 0) {
|
||||
NSLog(@"🔧 [Manager] 没有需要移除的用户,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从缓存移除
|
||||
[self removeCpEntriesForUids:uids];
|
||||
// 从UI移除
|
||||
[self removeMidpointRectsForUids:uids];
|
||||
|
||||
NSLog(@"🔧 [Manager] CP数据移除完成");
|
||||
}
|
||||
|
||||
#pragma mark - Dealloc
|
||||
|
||||
- (void)setupNotifications {
|
||||
|
@@ -1071,7 +1071,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
|
||||
// 🔧 新增:stage view类型变化时调用CP相关API
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
[self callMicCpListByUidListOnMicChangeWithQueue:currentQueue];
|
||||
[self callMicCpListByUidListWithQueue:currentQueue];
|
||||
|
||||
// 🔧 新增:检查19 mic房间中央位置(position 6)用户资格
|
||||
[self checkCentralPositionUserQualification:currentQueue];
|
||||
@@ -2566,10 +2566,52 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CustomMessageType_CP:
|
||||
switch (attachment.second) {
|
||||
case Custom_Message_Sub_CP_Binding:
|
||||
case Custom_Message_Sub_CP_Upgrade:
|
||||
[self handleCPBindingOrUpgradeMessage:attachment];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理CP绑定或升级消息
|
||||
- (void)handleCPBindingOrUpgradeMessage:(AttachmentModel *)attachment {
|
||||
NSLog(@"🔧 处理CP绑定或升级消息:first=%ld, second=%ld", (long)attachment.first, (long)attachment.second);
|
||||
|
||||
// 只有在完成进房初始化后才处理CP相关逻辑
|
||||
if (!self.hasCompletedRoomInitialization) {
|
||||
NSLog(@"🔧 进房初始化中,跳过CP绑定/升级处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前麦位队列
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
if (!currentQueue) {
|
||||
NSLog(@"⚠️ 无法获取当前麦位队列,跳过CP绑定/升级处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用 MicMidpointRectManager 处理CP绑定/升级消息
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
// 计算麦位总数
|
||||
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
|
||||
[manager handleCPBindingOrUpgradeMessageWithStageView:self.stageView
|
||||
micCount:micCount
|
||||
queue:currentQueue];
|
||||
}
|
||||
|
||||
// 调用CP API更新状态
|
||||
[self callMicCpListByUidListWithQueue:currentQueue];
|
||||
|
||||
NSLog(@"✅ CP绑定/升级消息处理完成");
|
||||
}
|
||||
|
||||
/// 处理麦位变化相关的CP逻辑
|
||||
- (void)handleMicChangeForCP:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSLog(@"🔧 处理麦位变化相关的CP逻辑");
|
||||
@@ -2577,19 +2619,22 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
// 更新当前用户的麦位状态
|
||||
[self updateCurrentUserMicStatus:queue];
|
||||
|
||||
// 更新麦位快照
|
||||
[self updateMicMidpointRectManagerSnapshot];
|
||||
|
||||
// 只有在完成进房初始化后才处理CP相关逻辑
|
||||
if (self.hasCompletedRoomInitialization) {
|
||||
// 检测下麦用户并处理CP关系缓存
|
||||
[self handleDownMicEventIfNeeded:queue];
|
||||
|
||||
// 🔧 新增:处理用户切换mic场景,确保所有CP SVGA状态正确更新
|
||||
[self handleMicSwitchScenarioIfNeeded:queue];
|
||||
// 使用 MicMidpointRectManager 处理CP逻辑
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
// 计算麦位总数
|
||||
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
|
||||
[manager handleMicChangeForCPWithStageView:self.stageView
|
||||
micCount:micCount
|
||||
queue:queue
|
||||
currentUserUid:[AccountInfoStorage instance].getUid.integerValue
|
||||
roomType:self.roomInfo.type];
|
||||
}
|
||||
|
||||
// 调用CP API
|
||||
[self callMicCpListByUidListOnMicChangeWithQueue:queue];
|
||||
[self callMicCpListByUidListWithQueue:queue];
|
||||
|
||||
// 🔧 新增:检查19 mic房间中央位置用户资格
|
||||
[self checkCentralPositionUserQualification:queue];
|
||||
@@ -2640,8 +2685,11 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
// 更新当前CP列表
|
||||
self.currentCpList = cpList.copy;
|
||||
|
||||
// 更新 MicMidpointRectManager 的缓存
|
||||
[self updateMicMidpointRectManagerCache:cpList];
|
||||
// 使用 MicMidpointRectManager 处理麦位关系CP消息
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
[manager handleMicRelationshipCPMessage:cpList];
|
||||
}
|
||||
|
||||
// 刷新CP SVGA显示
|
||||
[self drawSocialStageMidpointRects];
|
||||
@@ -3208,28 +3256,42 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
[[RoomBoomManager sharedManager] receiveEnterRoomBoom:model];
|
||||
}
|
||||
|
||||
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
|
||||
self.currentCpList = cpList;
|
||||
// 写入 MicMidpointRectManager 缓存后再刷新绘制
|
||||
[self updateMicMidpointRectManagerCache:cpList];
|
||||
// 刷新绘制,按CP关系播放对应SVGA
|
||||
[self drawSocialStageMidpointRects];
|
||||
}
|
||||
/// 统一的CP API成功回调方法
|
||||
- (void)handleMicCpListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
NSLog(@"🔧 CP API成功回调:接收到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
|
||||
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
self.currentCpList = cpList;
|
||||
|
||||
// 🔧 :更新 MicMidpointRectManager 的缓存
|
||||
[self updateMicMidpointRectManagerCache:cpList];
|
||||
|
||||
// 刷新绘制,按CP关系播放对应SVGA
|
||||
[self drawSocialStageMidpointRects];
|
||||
// 使用 MicMidpointRectManager 更新CP列表缓存并重绘
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
// 计算麦位总数
|
||||
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
|
||||
[manager updateCpListCacheAndRedraw:cpList
|
||||
stageView:self.stageView
|
||||
micCount:micCount
|
||||
roomType:self.roomInfo.type];
|
||||
}
|
||||
|
||||
// 如果当前用户麦位状态发生变化(上麦、下麦、换位),发送 NIM message
|
||||
if (self.currentUserMicStatusChanged) {
|
||||
[self sendMicRelationshipNIMessage:cpList];
|
||||
self.currentUserMicStatusChanged = NO; // 重置标志
|
||||
}
|
||||
|
||||
NSLog(@"🔧 CP API成功回调:处理完成");
|
||||
}
|
||||
|
||||
/// 按房间UID获取CP列表成功回调
|
||||
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
|
||||
NSLog(@"🔧 按房间UID获取CP列表成功:接收到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
[self handleMicCpListSuccess:cpList];
|
||||
}
|
||||
|
||||
/// 按用户UID列表获取CP列表成功回调
|
||||
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
|
||||
NSLog(@"🔧 按用户UID列表获取CP列表成功:接收到 %lu 条CP数据", (unsigned long)cpList.count);
|
||||
[self handleMicCpListSuccess:cpList];
|
||||
}
|
||||
|
||||
#pragma mark - 首次退出非自己的房间,处理是否需要弹新用户充值优惠
|
||||
@@ -3640,110 +3702,17 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *stageViewClass = NSStringFromClass([self.stageView class]);
|
||||
NSLog(@"🔧 开始绘制 %@ 中点矩形", stageViewClass);
|
||||
|
||||
// 移除旧的调试矩形
|
||||
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
// 使用新的管理器移除所有中点矩形
|
||||
id manager = [self.stageView valueForKey:@"midpointRectManager"];
|
||||
if ([manager respondsToSelector:@selector(removeAllMidpointRects)]) {
|
||||
[manager removeAllMidpointRects];
|
||||
}
|
||||
// 设置房间类型到管理器
|
||||
if ([manager respondsToSelector:@selector(setRoomType:)]) {
|
||||
[manager setRoomType:self.roomInfo.type];
|
||||
}
|
||||
// 使用 MicMidpointRectManager 绘制社交舞台中点矩形
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
// 计算麦位总数
|
||||
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
|
||||
[manager drawSocialStageMidpointRectsWithStageView:self.stageView
|
||||
micCount:micCount
|
||||
roomType:self.roomInfo.type];
|
||||
} else {
|
||||
// 兼容旧方式
|
||||
NSArray<UIView *> *subviews = [self.stageView.subviews copy];
|
||||
for (UIView *view in subviews) {
|
||||
if (view.tag == 56002) {
|
||||
[view removeFromSuperview];
|
||||
NSLog(@"🔧 无法获取 midpointRectManager,跳过中点矩形绘制");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据不同的 StageView 类型绘制相应的中点矩形
|
||||
NSArray *validPairs = nil;
|
||||
|
||||
if ([self.stageView isKindOfClass:[SocialStageView class]]) {
|
||||
validPairs = @[@[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8]];
|
||||
} else if ([self.stageView isKindOfClass:[TenMicStageView class]]) {
|
||||
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9]];
|
||||
} else if ([self.stageView isKindOfClass:[FifteenMicStageView class]]) {
|
||||
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14]];
|
||||
} else if ([self.stageView isKindOfClass:[NineteenMicStageView class]]) {
|
||||
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@8, @9], @[@10, @11], @[@12, @13], @[@14, @15], @[@15, @16], @[@16, @17], @[@17, @18]];
|
||||
} else if ([self.stageView isKindOfClass:[TwentyMicStageView class]]) {
|
||||
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14], @[@15, @16], @[@16, @17], @[@17, @18], @[@18, @19]];
|
||||
} else if ([self.stageView isKindOfClass:[AnchorStageView class]]) {
|
||||
validPairs = @[@[@1, @2], @[@2, @3]];
|
||||
} else if ([self.stageView isKindOfClass:[DatingStageView class]]) {
|
||||
validPairs = @[@[@1, @2], @[@3, @4], @[@5, @6], @[@7, @8]];
|
||||
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
|
||||
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@4, @5]];
|
||||
} else if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
|
||||
// 根据实际麦位数量动态生成相邻对
|
||||
NSInteger micCount = [self.stageView countOfMicroView];
|
||||
NSMutableArray *pairs = [NSMutableArray array];
|
||||
for (NSInteger i = 0; i < micCount - 1; i++) {
|
||||
[pairs addObject:@[@(i), @(i + 1)]];
|
||||
}
|
||||
validPairs = pairs;
|
||||
} else if ([self.stageView isKindOfClass:[AnchorPKStageView class]]) {
|
||||
validPairs = @[@[@0, @1]];
|
||||
} else {
|
||||
NSLog(@"🔧 未支持的 StageView 类型: %@", stageViewClass);
|
||||
return;
|
||||
}
|
||||
|
||||
NSLog(@"🔧 开始绘制 %@ 中点矩形,共 %lu 对相邻麦位", stageViewClass, (unsigned long)validPairs.count);
|
||||
|
||||
for (NSArray *pair in validPairs) {
|
||||
NSInteger firstIndex = [pair[0] integerValue];
|
||||
NSInteger secondIndex = [pair[1] integerValue];
|
||||
|
||||
CGRect rect = [self.stageView rectForMidpointBetweenMicAtIndex:firstIndex andIndex:secondIndex];
|
||||
if (!CGRectIsEmpty(rect)) {
|
||||
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
|
||||
micRelationshipView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
|
||||
micRelationshipView.layer.borderColor = [UIColor blueColor].CGColor;
|
||||
micRelationshipView.layer.borderWidth = 2.0;
|
||||
micRelationshipView.layer.cornerRadius = 8.0;
|
||||
micRelationshipView.tag = 56002;
|
||||
micRelationshipView.userInteractionEnabled = NO;
|
||||
|
||||
// 添加标签显示麦位对
|
||||
UILabel *label = [[UILabel alloc] init];
|
||||
label.text = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
|
||||
label.textColor = [UIColor whiteColor];
|
||||
label.font = [UIFont boldSystemFontOfSize:12];
|
||||
label.textAlignment = NSTextAlignmentCenter;
|
||||
label.frame = micRelationshipView.bounds;
|
||||
[micRelationshipView addSubview:label];
|
||||
|
||||
// 统一逻辑:优先通过 midpointRectManager 管理器添加与播放SVGA;无管理器时回退为直接添加
|
||||
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
id manager = [self.stageView valueForKey:@"midpointRectManager"];
|
||||
if ([manager respondsToSelector:@selector(addRelationshipAtFrame:micPairText:leftUid:rightUid:cpList:)]) {
|
||||
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
|
||||
UIView<MicroViewProtocol> *leftView = [self.stageView findMicroViewByIndex:firstIndex];
|
||||
UIView<MicroViewProtocol> *rightView = [self.stageView findMicroViewByIndex:secondIndex];
|
||||
NSInteger leftUid = [[leftView getUser] uid];
|
||||
NSInteger rightUid = [[rightView getUser] uid];
|
||||
[manager addRelationshipAtFrame:rect micPairText:micPairText leftUid:leftUid rightUid:rightUid cpList:self.currentCpList ?: @[]];
|
||||
}
|
||||
} else {
|
||||
[self.stageView addSubview:micRelationshipView];
|
||||
}
|
||||
NSLog(@"🔧 绘制中点矩形: %ld-%ld, rect: %@", (long)firstIndex, (long)secondIndex, NSStringFromCGRect(rect));
|
||||
} else {
|
||||
NSLog(@"🔧 跳过无效麦位对: %ld-%ld", (long)firstIndex, (long)secondIndex);
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"🔧 %@ 中点矩形绘制完成", stageViewClass);
|
||||
}
|
||||
|
||||
/// 进房成功后调用CP相关API
|
||||
@@ -3783,7 +3752,8 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
if (currentUserMicPosition == -1) {
|
||||
NSLog(@"🔧 获取mic用户列表:当前用户不在麦上,返回空数据");
|
||||
// 通知 manager 移除该用户 UID 的相关数据
|
||||
[self removeCurrentUserCpDataFromManager];
|
||||
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
|
||||
[self removeCpDataForUids:@[@(currentUid)]];
|
||||
return micUserUids;
|
||||
}
|
||||
|
||||
@@ -3839,12 +3809,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
}
|
||||
}
|
||||
|
||||
// 如果只有当前用户一个人,返回空数据
|
||||
// 🔧 修复:即使只有当前用户一个人,也返回当前用户的UID,确保能触发NIM message
|
||||
if (micUserUids.count == 1) {
|
||||
NSLog(@"🔧 获取mic用户列表:只有当前用户一个人,返回空数据");
|
||||
// 通知 manager 移除该用户 UID 的相关数据
|
||||
[self removeCurrentUserCpDataFromManager];
|
||||
return [NSArray array];
|
||||
NSLog(@"🔧 获取mic用户列表:只有当前用户一个人,但仍需发送NIM message");
|
||||
// 不返回空数组,保持当前用户UID,确保能触发CP API和NIM message
|
||||
}
|
||||
|
||||
NSLog(@"🔧 获取mic用户列表:当前用户麦位 %ld,找到 %lu 个相关用户: %@",
|
||||
@@ -3852,6 +3820,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
return micUserUids;
|
||||
}
|
||||
|
||||
|
||||
/// 处理其他用户mic变化(包括切换场景)
|
||||
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo changeType:(NSInteger)changeType {
|
||||
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
@@ -3859,178 +3828,102 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
return;
|
||||
}
|
||||
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (!midpointRectManager) {
|
||||
NSLog(@"🔧 处理其他用户mic变化:无法获取 midpointRectManager,跳过处理");
|
||||
// 获取当前麦位队列
|
||||
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
|
||||
if (!currentQueue) {
|
||||
NSLog(@"🔧 处理其他用户mic变化:无法获取当前麦位队列,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置房间类型
|
||||
midpointRectManager.roomType = self.roomInfo.type;
|
||||
// 使用 MicMidpointRectManager 处理其他用户mic变化
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
// 计算麦位总数
|
||||
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
|
||||
[manager handleOtherUserMicChange:userInfo
|
||||
changeType:changeType
|
||||
stageView:self.stageView
|
||||
micCount:micCount
|
||||
queue:currentQueue
|
||||
roomType:self.roomInfo.type];
|
||||
}
|
||||
|
||||
NSInteger userUid = userInfo.uid;
|
||||
NSArray<NSNumber *> *userUids = @[@(userUid)];
|
||||
// 处理API调用
|
||||
if (changeType == 2) { // 其他用户下麦
|
||||
// 获取剩余用户列表
|
||||
NSMutableArray<NSString *> *remainingUids = [NSMutableArray array];
|
||||
for (NSString *positionKey in currentQueue.allKeys) {
|
||||
MicroQueueModel *micModel = currentQueue[positionKey];
|
||||
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
|
||||
[remainingUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
|
||||
}
|
||||
}
|
||||
|
||||
if (changeType == 2) {
|
||||
// 其他用户下麦
|
||||
NSLog(@"🔧 处理其他用户下麦:UID %ld", (long)userUid);
|
||||
// 调用API更新剩余用户的CP状态
|
||||
if (remainingUids.count > 0) {
|
||||
[self.presenter micCpListByUidList:remainingUids];
|
||||
}
|
||||
|
||||
// 更新快照
|
||||
[self updateMicMidpointRectManagerSnapshot];
|
||||
|
||||
// 清除与该用户相关的cp与SVGA
|
||||
[midpointRectManager removeCpEntriesForUids:userUids];
|
||||
[midpointRectManager removeMidpointRectsForUids:userUids];
|
||||
|
||||
// 重绘(根据现有缓存)
|
||||
// 重绘
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
NSLog(@"🔧 其他用户下麦处理完成:UID %ld", (long)userUid);
|
||||
} else if (changeType == 1) {
|
||||
// 其他用户上麦
|
||||
NSLog(@"🔧 处理其他用户上麦:UID %ld", (long)userUid);
|
||||
} else if (changeType == 1) { // 其他用户上麦
|
||||
// 调用CP API更新状态
|
||||
[self callMicCpListByUidListWithQueue:currentQueue];
|
||||
|
||||
// 更新快照
|
||||
[self updateMicMidpointRectManagerSnapshot];
|
||||
|
||||
// 重新绘制所有CP关系(包括新上麦用户可能产生的CP关系)
|
||||
// 重新绘制所有CP关系
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
NSLog(@"🔧 其他用户上麦处理完成:UID %ld", (long)userUid);
|
||||
}
|
||||
}
|
||||
|
||||
/// 移除当前用户的CP数据从manager中
|
||||
- (void)removeCurrentUserCpDataFromManager {
|
||||
|
||||
/// 通用的CP数据移除方法
|
||||
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids {
|
||||
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
NSLog(@"🔧 移除当前用户CP数据:stageView 不支持 midpointRectManager,跳过处理");
|
||||
NSLog(@"🔧 移除CP数据:stageView 不支持 midpointRectManager,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
|
||||
NSArray<NSNumber *> *removedUids = @[@(currentUid)];
|
||||
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
// 设置房间类型
|
||||
midpointRectManager.roomType = self.roomInfo.type;
|
||||
// 从缓存移除
|
||||
[midpointRectManager removeCpEntriesForUids:removedUids];
|
||||
// 从UI移除
|
||||
[midpointRectManager removeMidpointRectsForUids:removedUids];
|
||||
NSLog(@"🔧 移除当前用户CP数据完成:UID %ld", (long)currentUid);
|
||||
}
|
||||
}
|
||||
|
||||
/// 处理用户切换mic场景,确保所有CP SVGA状态正确更新
|
||||
- (void)handleMicSwitchScenarioIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
NSLog(@"🔧 处理切换mic场景:stageView 不支持 midpointRectManager,跳过处理");
|
||||
if (uids.count == 0) {
|
||||
NSLog(@"🔧 移除CP数据:没有需要移除的用户,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 🔧 改进:基于当前用户麦位状态变化来检测切换场景
|
||||
// 检查当前用户是否发生了麦位变化
|
||||
BOOL hasMicPositionChanged = self.currentUserMicStatusChanged;
|
||||
|
||||
if (hasMicPositionChanged) {
|
||||
NSLog(@"🔧 检测到当前用户麦位状态变化,可能是切换mic场景");
|
||||
|
||||
// 获取当前舞台类型的麦位总数
|
||||
NSInteger micCount = 0;
|
||||
if (self.roomInfo) {
|
||||
switch (self.roomInfo.type) {
|
||||
case RoomType_Room: micCount = 9; break;
|
||||
case RoomType_10Mic: micCount = 10; break;
|
||||
case RoomType_15Mic: micCount = 15; break;
|
||||
case RoomType_19Mic: micCount = 19; break;
|
||||
case RoomType_20Mic: micCount = 20; break;
|
||||
default: micCount = 9; break;
|
||||
}
|
||||
}
|
||||
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
// 设置房间类型
|
||||
midpointRectManager.roomType = self.roomInfo.type;
|
||||
|
||||
// 对于麦位变化场景,需要重新构建所有CP关系
|
||||
// 1. 清除所有现有的中点矩形和SVGA
|
||||
[midpointRectManager removeAllMidpointRects];
|
||||
|
||||
// 2. 重新构建麦位快照
|
||||
[midpointRectManager rebuildMicSnapshotWithStageView:self.stageView micCount:micCount];
|
||||
|
||||
// 3. 重新绘制所有CP关系
|
||||
[self drawSocialStageMidpointRects];
|
||||
|
||||
NSLog(@"🔧 用户麦位变化场景处理完成:重新构建了所有CP关系");
|
||||
}
|
||||
|
||||
// 🔧 注意:不在这里重置状态标志,等待API成功回调后再重置
|
||||
// 状态标志将在 getMicCpListByUidListSuccess 中重置,确保能发送云信消息
|
||||
} else {
|
||||
NSLog(@"🔧 当前用户麦位状态未变化,跳过切换场景处理");
|
||||
// 使用 MicMidpointRectManager 移除CP数据
|
||||
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (manager) {
|
||||
[manager removeCpDataForUids:uids];
|
||||
NSLog(@"🔧 移除CP数据完成:UIDs %@", uids);
|
||||
}
|
||||
}
|
||||
|
||||
/// 检测并处理下麦事件
|
||||
- (void)handleDownMicEventIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
|
||||
NSLog(@"🔧 处理下麦事件:stageView 不支持 midpointRectManager,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取当前舞台类型的麦位总数
|
||||
NSInteger micCount = 0;
|
||||
if (self.roomInfo) {
|
||||
switch (self.roomInfo.type) {
|
||||
case RoomType_Room: micCount = 9; break;
|
||||
case RoomType_10Mic: micCount = 10; break;
|
||||
case RoomType_15Mic: micCount = 15; break;
|
||||
case RoomType_19Mic: micCount = 19; break;
|
||||
case RoomType_20Mic: micCount = 20; break;
|
||||
default: micCount = 9; break;
|
||||
/// 统一的CP API调用方法
|
||||
- (void)callMicCpListByUidListWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSLog(@"🔧 调用CP API:开始获取mic用户列表");
|
||||
|
||||
// 直接从queue获取当前所有在mic上的用户uid列表,确保数据是最新的
|
||||
NSMutableArray<NSString *> *micUserUids = [NSMutableArray array];
|
||||
|
||||
if (queue) {
|
||||
for (NSString *positionKey in queue.allKeys) {
|
||||
MicroQueueModel *micModel = queue[positionKey];
|
||||
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
|
||||
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 MicMidpointRectManager 检测麦位变化
|
||||
// MicMidpointRectManager *midpointRectManager = [self.stageView midpointRectManager];
|
||||
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
|
||||
if (midpointRectManager) {
|
||||
// 设置房间类型
|
||||
midpointRectManager.roomType = self.roomInfo.type;
|
||||
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges =
|
||||
[midpointRectManager diffMicChangeWithStageView:self.stageView micCount:micCount];
|
||||
|
||||
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
|
||||
if (removedUids && removedUids.count > 0) {
|
||||
NSLog(@"🔧 检测到下麦用户:%@", removedUids);
|
||||
|
||||
// 调用 MicMidpointRectManager 处理下麦事件
|
||||
[midpointRectManager handleDownMicEvent:removedUids stageView:self.stageView micCount:micCount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// mic位变动时调用CP相关API
|
||||
- (void)callMicCpListByUidListOnMicChangeWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
NSLog(@"🔧 mic位变动:开始调用 micCpListByUidList API");
|
||||
|
||||
NSArray<NSString *> *micUserUids = [self getAllMicUserUidsWithQueue:queue];
|
||||
|
||||
if (micUserUids.count == 0) {
|
||||
NSLog(@"🔧 mic位变动:没有相关用户在mic上,跳过API调用");
|
||||
NSLog(@"🔧 调用CP API:没有用户在mic上,跳过API调用");
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用 micCpListByUidList 方法
|
||||
if ([micUserUids containsObject:[AccountInfoStorage instance].getUid]) {
|
||||
NSLog(@"🔧 mic位变动,且包含了当前用户:调用 micCpListByUidList: %@", micUserUids);
|
||||
NSLog(@"🔧 调用CP API:micCpListByUidList: %@", micUserUids);
|
||||
[self.presenter micCpListByUidList:micUserUids];
|
||||
}
|
||||
|
||||
NSLog(@"🔧 mic位变动:micCpListByUidList API调用完成");
|
||||
NSLog(@"🔧 调用CP API:完成");
|
||||
}
|
||||
|
||||
/// 初始化当前用户的麦位状态
|
||||
@@ -4294,6 +4187,18 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
||||
}
|
||||
}
|
||||
|
||||
/// 根据房间类型获取麦位总数
|
||||
- (NSInteger)getMicCountForRoomType:(NSInteger)roomType {
|
||||
switch (roomType) {
|
||||
case RoomType_Room: return 9;
|
||||
case RoomType_10Mic: return 10;
|
||||
case RoomType_15Mic: return 15;
|
||||
case RoomType_19Mic: return 19;
|
||||
case RoomType_20Mic: return 20;
|
||||
default: return 9;
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查19 mic房间中央位置(position 6)用户资格
|
||||
- (void)checkCentralPositionUserQualification:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
|
||||
// 只检查19 mic房间
|
||||
|
@@ -18,10 +18,10 @@
|
||||
@{@"code": @"zh-Hant", @"localizationCode": @"zh-Hant", @"displayName": @"繁體中文", @"isRTL": @NO},
|
||||
@{@"code": @"ar", @"localizationCode": @"ar", @"displayName": @"العربية", @"isRTL": @YES},
|
||||
@{@"code": @"tr", @"localizationCode": @"tr", @"displayName": @"Türkçe", @"isRTL": @NO},
|
||||
@{@"code": @"pt", @"localizationCode": @"pt-BR", @"displayName": @"Português (Brasil)", @"isRTL": @NO},
|
||||
@{@"code": @"pt-BR", @"localizationCode": @"pt-BR", @"displayName": @"Português (Brasil)", @"isRTL": @NO},
|
||||
@{@"code": @"es", @"localizationCode": @"es", @"displayName": @"Español", @"isRTL": @NO},
|
||||
@{@"code": @"ru", @"localizationCode": @"ru", @"displayName": @"Русский", @"isRTL": @NO},
|
||||
@{@"code": @"uz", @"localizationCode": @"uz", @"displayName": @"O'zbek", @"isRTL": @NO}
|
||||
@{@"code": @"uz-UZ", @"localizationCode": @"uz-UZ", @"displayName": @"O'zbek", @"isRTL": @NO}
|
||||
];
|
||||
});
|
||||
return languages;
|
||||
|
@@ -4145,7 +4145,7 @@ ineHeadView12" = "الحمل";
|
||||
"20.20.51_text_26" = "كن في VIP%@";
|
||||
"20.20.51_text_27" = "١ في كل مرة تقوم فيها بتحميل صورة رمزية ديناميكية سيقوم النظام بخصم %@ عملة من حسابك. يرجى التأكد من أن رصيد حسابك كافٍ\n\n٢ عملية المراجعة: بعد اكتمال التحميل، سيدخل النظام تلقائيًا عملية المراجعة. خلال هذه الفترة، يرجى عدم تحميل صورة رمزية جديدة مرة أخرى لتجنب التأثير على تقدم المراجعة.\n\n٣ نتائج المراجعة \n\nتمت المراجعة بنجاح: ستدخل الصورة الرمزية الديناميكية الجديدة حيز التنفيذ على الفور وسيتم عرضها للمستخدمين الآخرين.\n\nفشل المراجعة: سيقوم النظام تلقائيًا برد %@ عملة أنفقتها بعد اكتمال المراجعة. في نفس الوقت، ستتلقى إشعارًا من النظام.\n\n٤ عملية لا رجعة فيها: يرجى ملاحظة أنه بمجرد مراجعة الصورة الرمزية الديناميكية ودخولها حيز التنفيذ، فلن تتمكن من استعادتها إلى الصورة الرمزية السابقة.\n";
|
||||
"20.20.51_text_28" = "عرض الوقت:%@";
|
||||
"20.20.51_text_29" = "يجب أن يكون عدد الماس مضاعفات 1000";
|
||||
"20.20.51_text_29" = "يجب أن يكون عدد الماس مضاعفات %@";
|
||||
|
||||
"20.20.56_text_1" = "عدد المباريات الحالي غير كافٍ، فشلت المباراة. إعادة المباراة مرة أخرى؟";
|
||||
"20.20.56_text_2" = "فشلت المطابقة، تم إرجاع العملات التي استهلكتها إلى محفظتك";
|
||||
|
@@ -3932,7 +3932,7 @@
|
||||
"20.20.51_text_26" = "Be VIP%@";
|
||||
"20.20.51_text_27" = "1 Each time you upload a dynamic avatar, the system will deduct %@ coins from your account. Please make sure that your account balance is sufficient.\n2 Review process: After the upload is completed, the system will automatically enter the review process. During this period, please do not upload a new avatar again to avoid affecting the review progress.\n3 Review results: \nReview passed: Your new dynamic avatar will take effect immediately and be displayed to other users.\nReview failed: The system will automatically refund the %@ coins you spent after the review is completed. At the same time, you will receive a system notification.\n4 Irreversible operation: Please note that once the dynamic avatar is reviewed and takes effect, you will not be able to restore it to the previous avatar.\n";
|
||||
"20.20.51_text_28" = "View Time: %@";
|
||||
"20.20.51_text_29" = "Number of diamonds needs to be multiples of 1000";
|
||||
"20.20.51_text_29" = "Number of diamonds needs to be multiples of %@";
|
||||
|
||||
"20.20.56_text_1" = "The current number of matches is not enough, the match failed. Re-match again?";
|
||||
"20.20.56_text_2" = "Match failed, the coins you consumed has been returned to your wallet";
|
||||
|
@@ -1,9 +1,7 @@
|
||||
|
||||
|
||||
NSCameraUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda visitar, tomar fotos y subir sus fotos, y luego mostrarlas en su página de inicio personal para que otros lo vean";
|
||||
NSCameraUsageDescription = "\"MoliStar\" necesita su consentimiento para que pueda visitar, tomar fotos y cargar sus imágenes, y luego mostrarlas en su página de inicio personal para que otras personas las vean";
|
||||
NSLocalNetworkUsageDescription = "La aplicación descubrirá y se conectará a dispositivos en su red";
|
||||
NSLocationWhenInUseUsageDescription = "Se requiere su consentimiento antes de poder usar los servicios de ubicación y recomendar amigos cercanos";
|
||||
NSMicrophoneUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda realizar chat de voz";
|
||||
NSPhotoLibraryAddUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda almacenar fotos en el álbum";
|
||||
NSPhotoLibraryUsageDescription = "\"Molistar\" necesita su consentimiento antes de que pueda acceder al álbum y seleccionar las imágenes que necesita cargar, y luego mostrarlas en su página de inicio personal para que otros lo vean";
|
||||
NSUserTrackingUsageDescription = "Permítanos obtener su permiso de IDFA para brindarle actividades y servicios personalizados.Su información no se utilizará para otros fines sin su permiso.";
|
||||
NSLocationWhenInUseUsageDescription = "Se requiere su consentimiento antes de que pueda usar los servicios de ubicación y recomendar amigos cercanos";
|
||||
NSMicrophoneUsageDescription = "\"MoliStar\" necesita su consentimiento antes de poder realizar una conversación de voz";
|
||||
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" necesita su consentimiento antes de poder almacenar fotos en el álbum";
|
||||
NSPhotoLibraryUsageDescription = "\"MoliStar\" necesita su consentimiento para que pueda acceder al álbum y seleccionar las imágenes que necesita cargar, y luego mostrarlas en su página de inicio personal para que otras personas las vean";
|
||||
NSUserTrackingUsageDescription = "Permítanos obtener su permiso de idfa para proporcionarle actividades y servicios personalizados. Su información no se utilizará para otros fines sin su permiso";
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3228,7 +3228,7 @@
|
||||
"20.20.51_text_26" = "Seja VIP%@";
|
||||
"20.20.51_text_27" = "1 Cada envio de avatar dinâmico deduz %@ moedas. Verifique seu saldo.\n2 Revisão: Após o envio, o sistema entrará em revisão. Não envie novamente para não atrasar.\n3 Resultado: \nAprovado: Seu avatar será exibido.\nReprovado: As moedas serão reembolsadas e você será notificado.\n4 Operação irreversível: Após a aprovação, não é possível reverter.";
|
||||
"20.20.51_text_28" = "Horário da Visita: %@";
|
||||
"20.20.51_text_29" = "O número de diamantes precisa ser múltiplo de 1000";
|
||||
"20.20.51_text_29" = "O número de diamantes precisa ser múltiplo de %@";
|
||||
"20.20.56_text_1" = "Número atual de correspondências insuficiente, falha na correspondência. Tentar novamente?";
|
||||
"20.20.56_text_2" = "Falha na correspondência, as moedas gastas foram devolvidas à sua carteira.";
|
||||
"20.20.56_text_3" = "Mudar Relacionamento";
|
||||
|
@@ -1,9 +1,8 @@
|
||||
|
||||
|
||||
NSCameraUsageDescription ="\"MoliStar\" needs your consent before you can visit, take photos and upload your pictures, and then display them on your personal homepage for others to view";
|
||||
NSLocalNetworkUsageDescription ="The app will discover and connect to devices on your network";
|
||||
NSLocationWhenInUseUsageDescription = "Your consent is required before you can use location services and recommend nearby friends";
|
||||
NSMicrophoneUsageDescription = "\"MoliStar\" needs your consent before it can conduct voice chat";
|
||||
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" needs your consent before it can store photos in the album";
|
||||
NSPhotoLibraryUsageDescription = "\"MoliStar\" needs your consent before you can access the album and select the pictures you need to upload, and then display them on your personal homepage for others to view";
|
||||
NSUserTrackingUsageDescription = "Please allow us to obtain your idfa permission to provide you with personalized activities and services. your information will not be used for other purposes without your permission";
|
||||
NSCameraUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как вы можете посетить, фотографировать и загружать ваши изображения, а затем отображать их на вашей персональной странице для просмотра другими людьми";
|
||||
NSLocalNetworkUsageDescription = "Приложение обнаружит и подключится к устройствам в вашей сети";
|
||||
NSLocationWhenInUseUsageDescription = "Вам необходимо дать согласие, прежде чем вы сможете использовать службы определения местоположения и рекомендовать близких друзей";
|
||||
NSMicrophoneUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как он может проводить голосовый чат";
|
||||
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как он может хранить фотографии в альбоме";
|
||||
NSPhotoLibraryUsageDescription = "\"MoliStar\" нужен ваш consentimiento перед тем, как вы можете получить доступ к альбому и выбрать изображения, которые вам нужно загрузить, а затем отобразить их на вашей персональной странице для просмотра другими людьми";
|
||||
NSUserTrackingUsageDescription = "Пожалуйста, разрешите нам получить ваше разрешение на idfa, чтобы предоставить вам персонализированные мероприятия и услуги. ваша информация не будет использоваться для других целей без вашего разрешения";
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3726,7 +3726,7 @@
|
||||
"20.20.51_text_26" = "VIP%@ olun";
|
||||
"20.20.51_text_27" = "1 Her dinamik avatar yüklediğinizde, sistem hesabınızdan %@ jeton düşecektir. Lütfen hesap bakiyenizin yeterli olduğundan emin olun.\n2 İnceleme süreci: Yükleme tamamlandıktan sonra, sistem otomatik olarak inceleme sürecine girecektir. Bu süre zarfında, inceleme ilerlemesini etkilememek için lütfen tekrar yeni bir avatar yüklemeyin.\n3 İnceleme sonuçları: \nİnceleme geçti: Yeni dinamik avatarınız hemen yürürlüğe girecek ve diğer kullanıcılara gösterilecektir.\nİnceleme başarısız oldu: Sistem, inceleme tamamlandıktan sonra harcadığınız %@ jetonu otomatik olarak iade edecektir. Aynı zamanda, bir sistem bildirimi alacaksınız.\n4 Geri alınamaz işlem: Lütfen dinamik avatar incelendikten ve yürürlüğe girdikten sonra, onu önceki avatarınıza geri yükleyemeyeceğinizi unutmayın.\n";
|
||||
"20.20.51_text_28" = "Görüntüleme Süresi: %@";
|
||||
"20.20.51_text_29" = "Elmas sayısının 1000 katları olması gerekir";
|
||||
"20.20.51_text_29" = "Elmas sayısının %@ katları olması gerekir";
|
||||
|
||||
"20.20.56_text_1" = "Mevcut eşleşme sayısı yeterli değil, eşleşme başarısız oldu. Tekrar eşleşelim mi?";
|
||||
"20.20.56_text_2" = "Eşleşme başarısız oldu, harcadığınız jetonlar cüzdanınıza iade edildi";
|
||||
|
@@ -1,9 +1,7 @@
|
||||
|
||||
|
||||
NSCameraUsageDescription ="\"MoliStar\" needs your consent before you can visit, take photos and upload your pictures, and then display them on your personal homepage for others to view";
|
||||
NSLocalNetworkUsageDescription ="The app will discover and connect to devices on your network";
|
||||
NSLocationWhenInUseUsageDescription = "Your consent is required before you can use location services and recommend nearby friends";
|
||||
NSMicrophoneUsageDescription = "\"MoliStar\" needs your consent before it can conduct voice chat";
|
||||
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" needs your consent before it can store photos in the album";
|
||||
NSPhotoLibraryUsageDescription = "\"MoliStar\" needs your consent before you can access the album and select the pictures you need to upload, and then display them on your personal homepage for others to view";
|
||||
NSUserTrackingUsageDescription = "Please allow us to obtain your idfa permission to provide you with personalized activities and services. your information will not be used for other purposes without your permission";
|
||||
NSCameraUsageDescription = "\"MoliStar\" sizning rozilingizni talab qiladi, siz tashrif buyurish, fotosurat olish va rasmlaringizni yuklashdan oldin, keyin ularni shaxsiy asosiy sahifangizda boshqalar ko'rishi uchun ko'rsatish";
|
||||
NSLocalNetworkUsageDescription = "Ilova tarmog'ingizdagi qurilmalarni topadi va ulanadi";
|
||||
NSLocationWhenInUseUsageDescription = "Siz joylashuv xizmatlaridan foydalanishingiz va yaqin do'stlarni tavsiya qilishingizdan oldin rozilingiz kerak";
|
||||
NSMicrophoneUsageDescription = "\"MoliStar\" ovozli suhbat olib borishdan oldin sizning rozilingizni talab qiladi";
|
||||
NSPhotoLibraryAddUsageDescription = "\"MoliStar\" fotosuratlarni albomda saqlashdan oldin sizning rozilingizni talab qiladi";
|
||||
NSPhotoLibraryUsageDescription = "\"MoliStar\" albomga kirish va yuklash kerak bo'lgan rasmlarni tanlashdan oldin sizning rozilingizni talab qiladi, keyin ularni shaxsiy asosiy sahifangizda boshqalar ko'rishi uchun ko'rsatish";
|
||||
NSUserTrackingUsageDescription = "Iltimos, sizga shaxsiy aktivlar va xizmatlarni taqdim etish uchun idfa ruxsatini olishimizga ruxsat bering. Sizning ma'lumotlaringiz sizning ruxsatingizsiz boshqa maqsadlar uchun ishlatilmaydi";
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3596,7 +3596,7 @@
|
||||
"20.20.51_text_26" = "成為 VIP%@";
|
||||
"20.20.51_text_27" = "1 每次上傳動態頭像,系統都會從您的帳戶中扣除%@金幣。請確保您的帳戶餘額充足。\n2 審核流程:上傳完成後,系統自動進入審核流程。在此期間,請勿再次上傳新頭像,以免影響審核進度。\n3 審核結果: \n審核通過:您的新動態頭像將立即生效並顯示給其他使用者。\n審核失敗:審核完成後系統將自動退還您花費的%@金幣。同時,您也會收到系統通知。\n4 不可逆操作:請注意,動態頭像一旦審核並生效,將無法恢復為先前的頭像。\n";
|
||||
"20.20.51_text_28" = "访客時間:%@";
|
||||
"20.20.51_text_29" = "鑽石數量需要是1000的倍數";
|
||||
"20.20.51_text_29" = "鑽石數量需要是 %@ 的倍數";
|
||||
|
||||
"20.20.56_text_1" = "目前的匹配次數不足,匹配失敗。再次匹配?";
|
||||
"20.20.56_text_2" = "匹配失敗,您消耗的硬幣已返回您的錢包";
|
||||
|
56
migration_test.md
Normal file
56
migration_test.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# CP SVGA 逻辑迁移测试报告
|
||||
|
||||
## 迁移完成情况
|
||||
|
||||
### ✅ 已完成的工作
|
||||
|
||||
1. **在 MicMidpointRectManager 中新增的 CP 业务逻辑方法:**
|
||||
- `handleMicChangeForCPWithStageView:micCount:queue:currentUserUid:roomType:`
|
||||
- `handleCPBindingOrUpgradeMessageWithStageView:micCount:queue:`
|
||||
- `handleMicRelationshipCPMessage:`
|
||||
- `handleOtherUserMicChange:changeType:stageView:micCount:queue:roomType:`
|
||||
- `handleMicSwitchScenarioIfNeededWithStageView:micCount:queue:currentUserUid:roomType:`
|
||||
- `handleDownMicEventIfNeededWithStageView:micCount:queue:roomType:`
|
||||
- `updateCpListCacheAndRedraw:stageView:micCount:roomType:`
|
||||
- `drawSocialStageMidpointRectsWithStageView:micCount:roomType:`
|
||||
- `removeCpDataForUids:`
|
||||
|
||||
2. **在 XPRoomViewController 中简化的方法调用:**
|
||||
- 所有 CP 相关方法现在都直接调用 MicMidpointRectManager 的对应方法
|
||||
- 添加了 `getMicCountForRoomType:` 方法来计算麦位总数
|
||||
- 移除了冗余的 CP 相关方法
|
||||
|
||||
3. **头文件更新:**
|
||||
- 在 MicMidpointRectManager.h 中添加了所有新方法的声明
|
||||
- 添加了必要的类前向声明
|
||||
|
||||
### 🔧 修复的问题
|
||||
|
||||
1. **编译错误修复:**
|
||||
- 修复了 `self.micCount` 属性不存在的错误
|
||||
- 添加了 `getMicCountForRoomType:` 方法来动态计算麦位总数
|
||||
- 在头文件中添加了所有新方法的声明
|
||||
|
||||
2. **代码结构优化:**
|
||||
- 将 CP 业务逻辑从 ViewController 迁移到 Manager
|
||||
- 减少了代码重复
|
||||
- 提高了代码的内聚性
|
||||
|
||||
### 📊 迁移效果
|
||||
|
||||
- **代码行数减少**:XPRoomViewController 中 CP 相关代码大幅减少
|
||||
- **职责分离**:MicMidpointRectManager 专门负责 CP SVGA 逻辑
|
||||
- **可维护性提升**:CP 相关逻辑集中管理,修改更容易
|
||||
- **可测试性提升**:Manager 可以独立进行单元测试
|
||||
|
||||
### 🎯 Linus 式优势
|
||||
|
||||
✅ **单一职责**:Manager 专门负责 CP SVGA 逻辑,ViewController 只负责调用
|
||||
✅ **减少重复**:消除了 ViewController 中的重复代码
|
||||
✅ **易于测试**:Manager 可以独立测试
|
||||
✅ **易于维护**:CP 相关逻辑集中在一个地方
|
||||
✅ **降低耦合**:ViewController 只负责调用,不处理具体逻辑
|
||||
|
||||
## 迁移完成!🎉
|
||||
|
||||
所有 CP SVGA 相关逻辑已成功从 XPRoomViewController 迁移到 MicMidpointRectManager 中,代码结构更加清晰,维护性大大提升。
|
Reference in New Issue
Block a user