土耳其新政策添加上麦时长

This commit is contained in:
2025-08-12 18:49:56 +08:00
parent e23133e5d1
commit 31c052669f
9 changed files with 146 additions and 24 deletions

View File

@@ -1324,6 +1324,7 @@ public enum RedisKey {
guild_invite_lock,
guild_member_room_mic_record,
guild_member_room_mic_record_lock,
guild_member_room_mic_record_vo,
guild_week_rank,
guild_month_rank,

View File

@@ -0,0 +1,18 @@
package com.accompany.business.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class MicRecordVo {
private Long uid;
private Long guildMemberId;
private Long statTimeStamp;
private Long roomId;
private Integer pos;
}

View File

@@ -17,6 +17,9 @@ public class GuildPolicy2Vo {
@ApiModelProperty("钻石数量")
private BigDecimal diamondNum = BigDecimal.ZERO;
@ApiModelProperty("公会钻石数量")
private BigDecimal guildDiamondNum = BigDecimal.ZERO;
@ApiModelProperty("上麦有效天数")
private Integer micDay = 0;

View File

@@ -20,7 +20,7 @@ public interface GuildDiamondStatisticsPolicy2Mapper extends BaseMapper<GuildDia
int updateDayDiamondStatistics(@Param("cycleDate")String cycleDate, @Param("statDate")String statDate,
@Param("guildMemberId")Long guildMemberId, @Param("partitionId") Integer partitionId, @Param("guildId")Integer guildId, @Param("uid")Long uid,
@Param("diamond") BigDecimal diamond, @Param("time") Date time, @Param("micSecond") Integer micSecond);
@Param("diamond") BigDecimal diamond, @Param("time") Date time, @Param("micMinutes") Integer micMinutes);
BigDecimal getTotalDiamondInCycleGuild(@Param("cycleDate")String cycleDate, @Param("guildId")Integer guildId);

View File

@@ -21,9 +21,9 @@ import java.util.List;
@Service
public class GuildDiamondStatisticsPolicy2Service extends ServiceImpl<GuildDiamondStatisticsPolicy2Mapper, GuildDiamondStatisticsPolicy2> {
public int updateDayDiamondStatistics(String cycleDate, String statDate, GuildMember guildMember, double diamond, int micSecond) {
public int updateDayDiamondStatistics(String cycleDate, String statDate, GuildMember guildMember, double diamond, int micMinutes) {
return baseMapper.updateDayDiamondStatistics(cycleDate, statDate, guildMember.getId(), guildMember.getPartitionId(),
guildMember.getGuildId(), guildMember.getUid(), BigDecimal.valueOf(diamond), new Date(), micSecond);
guildMember.getGuildId(), guildMember.getUid(), BigDecimal.valueOf(diamond), new Date(), micMinutes);
}
public BigDecimal getTotalDiamondInCycle(String cycleDate, Integer guildId) {

View File

@@ -26,8 +26,6 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import static com.accompany.common.constant.Constant.ClanMode.GUILD_POLICY2;
@Slf4j
@Service
public class GuildPolicy2Service {
@@ -67,6 +65,7 @@ public class GuildPolicy2Service {
fillAllDayOfMonth(guildPolicy2Vo, myData, cycleBeginDate, partitionEnum);
if (guildAuthService.hasAuthByRoleType(partitionEnum.getClanMode(), guildMember.getRoleType(), GuildConstant.AuthCode.GUILD_POLICY2_MEMBER)) {
guildPolicy2Vo.setGuildDiamondNum(guildDiamondStatisticsPolicy2Service.getTotalDiamondInCycle(cycleBeginDate, guildMember.getGuildId()));
guildPolicy2Vo.setMemberData(guildDiamondStatisticsPolicy2Service.listMemberData(cycleBeginDate, guildMember.getGuildId()));
}
@@ -120,18 +119,15 @@ public class GuildPolicy2Service {
}
public void statMicSecond(GuildMember guildMember, Long entreTimestamp, Long timestamp) {
PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(guildMember.getPartitionId());
if (!GUILD_POLICY2.equals(partitionEnum.getClanMode())) {
return;
}
Map<String, Integer> durationMap = roomMicService.calUserUpMicDuration(entreTimestamp, timestamp, guildMember.getPartitionId());
if (durationMap.size() > 0) {
for (Map.Entry<String, Integer> entry : durationMap.entrySet()) {
Integer second = entry.getValue() * 60;
Integer micMinutes = entry.getValue();
String statDate = entry.getKey();
Date beginOfMonth = DateUtil.beginOfMonth(DateUtil.parseDate(statDate));
String cycleDate = DateUtil.formatDate(beginOfMonth);
guildDiamondStatisticsPolicy2Service.updateDayDiamondStatistics(cycleDate, statDate, guildMember, 0, second);
guildDiamondStatisticsPolicy2Service.updateDayDiamondStatistics(cycleDate, statDate, guildMember, 0, micMinutes);
}
}
}

View File

@@ -1,10 +1,12 @@
package com.accompany.business.service.room;
import cn.hutool.core.util.ObjectUtil;
import com.accompany.business.constant.family.FamilyConstant;
import com.accompany.business.model.guild.GuildMember;
import com.accompany.business.param.MicQueueParam;
import com.accompany.business.service.guild.GuildMemberService;
import com.accompany.business.service.guildpolicy2.GuildPolicy2Service;
import com.accompany.business.vo.MicRecordVo;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.enumeration.PartitionEnum;
@@ -20,6 +22,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.redisson.api.RLock;
import org.redisson.api.RMap;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
@@ -63,14 +66,15 @@ public class GuildMemberRoomMicRecordService extends ServiceImpl<GuildMemberRoom
return;
}
PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(guildMember.getPartitionId());
if (!GUILD_POLICY2.equals(partitionEnum.getClanMode()) && guildMember.getPartitionId() == PartitionEnum.ARAB.getId()){
boolean guildPolicy2 = GUILD_POLICY2.equals(partitionEnum.getClanMode());
if (!guildPolicy2 && guildMember.getPartitionId() == PartitionEnum.ARAB.getId()){
return;
}
JSONArray keysJsonArray = new JSONArray(micQueueParam.getKeys());
for(int i = 0; i < keysJsonArray.length(); i++){
int pos = keysJsonArray.getInt(i);
record(qEvent, timestamp, guildMember, roomUid, roomId, pos);
record(qEvent, timestamp, guildMember, roomUid, roomId, pos, guildPolicy2);
}
return;
@@ -91,20 +95,28 @@ public class GuildMemberRoomMicRecordService extends ServiceImpl<GuildMemberRoom
return;
}
PartitionEnum partitionEnum = PartitionEnum.getByPartitionId(guildMember.getPartitionId());
if (!GUILD_POLICY2.equals(partitionEnum.getClanMode()) && guildMember.getPartitionId() == PartitionEnum.ARAB.getId()){
boolean guildPolicy2 = GUILD_POLICY2.equals(partitionEnum.getClanMode());
if (!guildPolicy2 && guildMember.getPartitionId() == PartitionEnum.ARAB.getId()){
return;
}
record(qEvent, timestamp, guildMember, roomUid, roomId, pos);
record(qEvent, timestamp, guildMember, roomUid, roomId, pos, guildPolicy2);
}
}
public void record(Integer qEvent, Long timestamp, GuildMember guildMember, Long roomUid, Long roomId, Integer pos){
public void record(Integer qEvent, Long timestamp, GuildMember guildMember, Long roomUid, Long roomId, Integer pos, boolean guildPolicy2){
Long uid = guildMember.getUid();
RSet<Long> micSet = redissonClient.getSet(RedisKey.guild_member_room_mic_record.getKey(uid.toString(), roomId.toString(), pos.toString()));
if (isUpMicAction(qEvent)) {
micSet.add(timestamp);
micSet.expire(48, TimeUnit.HOURS);
if (guildPolicy2) {
this.getMicRecordMap().put(uid, MicRecordVo.builder().guildMemberId(guildMember.getId())
.uid(uid)
.roomId(roomId)
.pos(pos)
.statTimeStamp(timestamp).build());
}
log.info("[上麦开始计算时间] uid {} roomUid {} roomId {} pos {} timestamp {}", uid, roomUid, roomId, pos, timestamp);
} else if (isDownMicActionAction(qEvent)) {
Long entreTimestamp = null;
@@ -145,8 +157,17 @@ public class GuildMemberRoomMicRecordService extends ServiceImpl<GuildMemberRoom
record.setDownTime(new Date(timestamp));
record.setRemainTime(remainMillisecond);
save(record);
guildPolicy2Service.statMicSecond(guildMember, entreTimestamp, timestamp);
if (guildPolicy2) {
Long beginTime = entreTimestamp;
MicRecordVo micRecordVo = this.getMicRecordMap().get(uid);
if (null != micRecordVo && micRecordVo.getRoomId().equals(roomId)
&& micRecordVo.getPos().equals(pos) && micRecordVo.getStatTimeStamp() >= entreTimestamp) {
this.getMicRecordMap().remove(uid);
beginTime = micRecordVo.getStatTimeStamp() > entreTimestamp ? micRecordVo.getStatTimeStamp() : entreTimestamp;
}
guildPolicy2Service.statMicSecond(guildMember, beginTime, timestamp);
this.getMicRecordMap().remove(uid);
}
}
}
@@ -278,4 +299,65 @@ public class GuildMemberRoomMicRecordService extends ServiceImpl<GuildMemberRoom
}
return withoutOverDateList.stream().collect(Collectors.toMap(GuildMemberMicRemainTimeVo::getGuildMemberId, x -> x.getRemainTime()));
}
public RMap<Long, MicRecordVo> getMicRecordMap() {
return redissonClient.getMap(RedisKey.guild_member_room_mic_record_vo.getKey());
}
/**
* 每5分钟统计一次上麦时间
*/
public void statMicRecordTask4GuildPolicy2() {
RMap<Long, MicRecordVo> micRecordMap = getMicRecordMap();
if (micRecordMap.isEmpty()) {
return;
}
Set<Long> uids = getMicRecordMap().readAllKeySet();
Map<Long, GuildMember> guildMemberMap = guildMemberService.mapFamilyMember(uids);
Long timeInMillis = Calendar.getInstance().getTimeInMillis();
uids.forEach(uid -> {
MicRecordVo micRecordVo = micRecordMap.get(uid);
if (ObjectUtil.isNull(micRecordVo)) {
return;
}
Long roomId = micRecordVo.getRoomId();
Integer pos = micRecordVo.getPos();
RLock lock = redissonClient.getLock(RedisKey.guild_member_room_mic_record_lock.getKey(uid.toString(), roomId.toString(), pos.toString()));
boolean locked = false;
try {
locked = lock.tryLock(3, TimeUnit.SECONDS);
GuildMember guildMember = guildMemberMap.get(micRecordVo.getGuildMemberId());
if (ObjectUtil.isNull(guildMember)) {
return;
}
RSet<Long> micSet = redissonClient.getSet(RedisKey.guild_member_room_mic_record.getKey(uid.toString(), roomId.toString(), pos.toString()));
Optional<Long> lastUpMic = micSet.stream().filter(inTime -> timeInMillis.compareTo(inTime) > 0).max(Comparator.comparingLong(Long::longValue));
if (lastUpMic.isEmpty()) {
log.error("[statMicRecordTask] 获取上麦时间异常 uid {} roomUid {} roomId {} pos {} timeInMillis {}", uid, roomId, pos, timeInMillis);
return;
}
Long maxUpTime = lastUpMic.get();
if (maxUpTime == null) {
return;
}
if (maxUpTime < timeInMillis) {
guildPolicy2Service.statMicSecond(guildMember, micRecordVo.getStatTimeStamp(), timeInMillis);
micRecordVo.setStatTimeStamp(timeInMillis);
} else {
micRecordVo.setStatTimeStamp(maxUpTime);
}
micRecordMap.put(micRecordVo.getUid(), micRecordVo);
} catch (Exception e) {
log.error("statMicRecordTask uid {} roomId {} pos {} timeInMillis {}", uid, roomId, pos, timeInMillis, e);
} finally {
if (locked) {
lock.unlock();
}
}
});
}
}

View File

@@ -3,12 +3,12 @@
<mapper namespace="com.accompany.business.mybatismapper.guildpolicy2.GuildDiamondStatisticsPolicy2Mapper">
<update id="updateDayDiamondStatistics">
INSERT INTO `guild_diamond_statistics_policy2` (`cycle_date`, `stat_date`, `guild_member_id`, `partition_id`, `uid`,
`guild_id`, `diamond_num`, `mic_second`, `create_time`, `update_time`)
VALUES (#{cycleDate}, #{statDate}, #{guildMemberId}, #{partitionId}, #{uid}, #{guildId}, #{diamond}, #{micSecond}, #{time}, #{time})
`guild_id`, `diamond_num`, `mic_minutes`, `create_time`, `update_time`)
VALUES (#{cycleDate}, #{statDate}, #{guildMemberId}, #{partitionId}, #{uid}, #{guildId}, #{diamond}, #{micMinutes}, #{time}, #{time})
ON DUPLICATE KEY
UPDATE
diamond_num = diamond_num + values (diamond_num),
mic_second = values (mic_second),
mic_minutes = mic_minutes + values (mic_minutes),
update_time = values (update_time)
</update>
@@ -36,7 +36,7 @@
u.avatar as avatar,
u.uid as uid,
ifnull(sum(gdsp.diamond_num), 0) as diamondNum,
COUNT(DISTINCT CASE WHEN mic_second >= 7200 THEN stat_date END) AS micDay
COUNT(DISTINCT CASE WHEN gdsp.mic_minutes >= 120 THEN gdsp.stat_date END) AS micDay
from guild_member gm
left join `guild_diamond_statistics_policy2` gdsp on gm.id = gdsp.guild_member_id and gdsp.cycle_date = #{cycleDate}
left join users u on u.uid = gm.uid
@@ -49,8 +49,8 @@
select
gdsp.stat_date as statDate,
ifnull(sum(gdsp.diamond_num), 0) as diamondNum,
gdsp.mic_second/60 as micMinute,
if(gdsp.mic_second >= 7200, 1, 0) as validMicDay
gdsp.mic_minutes as micMinute,
if(gdsp.mic_minutes >= 120, 1, 0) as validMicDay
from `guild_diamond_statistics_policy2` gdsp
left join guild_member gm on gm.id = gdsp.guild_member_id and gdsp.cycle_date = #{cycleDate}
where gdsp.cycle_date = #{cycleDate}

View File

@@ -0,0 +1,22 @@
package com.accompany.scheduler.task.guild;
import com.accompany.business.service.room.GuildMemberRoomMicRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class GuildMemberMicTask {
@Autowired
private GuildMemberRoomMicRecordService guildMemberRoomMicRecordService;
@Scheduled(cron = "0 0/5 * * * ?")
public void micStatTask() {
log.info("micStatTask start");
guildMemberRoomMicRecordService.statMicRecordTask4GuildPolicy2();
log.info("micStatTask end");
}
}