新增碎片兑换接口

This commit is contained in:
tianfeng 2025-09-19 18:43:19 +08:00
parent 2fb09c2839
commit 31e7b3239f
10 changed files with 184 additions and 9 deletions

View File

@ -9,12 +9,14 @@ import com.red.circle.other.app.dto.clientobject.activity.WeekStarHistoryVO;
import com.red.circle.other.app.dto.clientobject.gift.GiftConfigCO;
import com.red.circle.other.app.dto.cmd.activity.WeekStarGiftQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarRankingQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarExchangeCmd;
import com.red.circle.other.app.service.activity.WeekStarService;
import com.red.circle.other.inner.model.dto.activity.props.ActivityResource;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -137,4 +139,17 @@ public class WeekStarRestController extends BaseController {
return weekStarService.getHistoryTop1(cmd);
}
/**
* 碎片兑换.
*
* @eo.name 碎片兑换
* @eo.url /exchange
* @eo.method post
* @eo.request-type formdata
*/
@PostMapping("/exchange")
public Long exchange(@Validated WeekStarExchangeCmd cmd) {
return weekStarService.exchange(cmd);
}
}

View File

@ -0,0 +1,114 @@
package com.red.circle.other.app.command.activity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.app.dto.cmd.activity.WeekStarExchangeCmd;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
import com.red.circle.other.infra.common.activity.send.SendRewardParam;
import com.red.circle.other.infra.database.mongo.entity.game.egg.GameEggStockConfig;
import com.red.circle.other.infra.database.rds.entity.game.GameUserShardsBackpack;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.endpoint.material.props.api.FragmentsBackpackClientApi;
import com.red.circle.other.inner.model.cmd.material.PrizeDescribe;
import com.red.circle.other.inner.model.dto.activity.props.ActivityPropsGroup;
import com.red.circle.other.inner.model.dto.activity.props.ActivityPropsRule;
import com.red.circle.other.inner.model.dto.activity.props.ActivityRewardProps;
import com.red.circle.other.inner.model.dto.material.FragmentsBackpackDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* 周星碎片兑换执行器.
*
* @author pengshigang on 2025/9/19
*/
@Component
@RequiredArgsConstructor
public class WeekStarExchangeExe {
private final FragmentsBackpackClientApi fragmentsBackpackClientApi;
private final PropsActivitySendCommon sendPropsManager;
private final PropsActivityClient propsActivityClient;
public Long execute(WeekStarExchangeCmd cmd) {
// 1. 校验碎片背包
List<FragmentsBackpackDTO> backpackList = fragmentsBackpackClientApi
.listByUserIdByFragmentsIds(cmd.getReqUserId(), Set.of(cmd.getFragmentsId()))
.getBody();
ResponseAssert.notEmpty(CommonErrorCode.DATA_ERROR, backpackList);
FragmentsBackpackDTO backpack = backpackList.get(0);
if (backpack.getQuantity() == null || backpack.getQuantity() <= 0) {
throw new RuntimeException("Insufficient amount of debris.");
}
ActivityPropsRule activityPropsRule = propsActivityClient.getByRuleId(cmd.getPropsGroupId()).getBody();
if (activityPropsRule == null) {
throw new RuntimeException("activityPropsRule is null.");
}
JSONObject obj = JSON.parseObject(activityPropsRule.getJsonData());
Integer needFragments = obj.getInteger("need_fragments");
if (needFragments == null || needFragments <= 0) {
throw new RuntimeException("needFragments is null or needFragments <= 0.");
}
if (backpack.getQuantity() < needFragments) {
throw new RuntimeException("Insufficient amount of debris.");
}
// 校验配置
ActivityPropsGroup body = propsActivityClient.getActivityPropsGroup(cmd.getReqSysOrigin().getOrigin(), activityPropsRule.getResourceGroupId()).getBody();
if (body == null || body.getActivityRewardProps().isEmpty()) {
throw new RuntimeException("ActivityPropsGroup is null.");
}
List<ActivityRewardProps> activityRewardProps = body.getActivityRewardProps();
ActivityRewardProps rewardProps = activityRewardProps.get(0);
// 2. 扣除碎片
fragmentsBackpackClientApi.decrFragments(
cmd.getReqUserId(),
Set.of(cmd.getFragmentsId()),
needFragments
);
// 发送奖品
sendPropsManager.sendGroup(SendRewardParam.builder()
.acceptUserId(cmd.getReqUserId())
.origin(SendPropsOrigin.EGG)
.sysOrigin(SysOriginPlatformEnum.valueOf(cmd.getReqSysOrigin().getOrigin()))
.trackId(cmd.getPropsGroupId())
.build(),
getPrizeDescribes(rewardProps));
// 4. 添加兑换记录 - 暂时不写
// TODO: 添加兑换记录
return 1L; // 返回兑换数量
}
private List<PrizeDescribe> getPrizeDescribes(ActivityRewardProps rewardProps) {
PrizeDescribe prize = new PrizeDescribe()
.setTrackId(rewardProps.getId())
.setType(rewardProps.getType())
.setDetailType(rewardProps.getDetailType())
.setContent(rewardProps.getContent())
.setQuantity(rewardProps.getQuantity());
return List.of(prize);
}
}

View File

@ -9,6 +9,7 @@ import com.red.circle.other.app.command.activity.query.WeekStarHistoryTop1QueryE
import com.red.circle.other.app.command.activity.query.WeekStarRewardQueryExe;
import com.red.circle.other.app.command.activity.query.WeekStarStartEndTimeQueryExe;
import com.red.circle.other.app.command.activity.query.WeekStarThisWeeksGiftQueryExe;
import com.red.circle.other.app.command.activity.WeekStarExchangeExe;
import com.red.circle.other.app.dto.clientobject.activity.LastWeekStarGiftUserRankCO;
import com.red.circle.other.app.dto.clientobject.activity.UserRankCO;
import com.red.circle.other.app.dto.clientobject.activity.WeekStarGiftUserRankCO;
@ -16,6 +17,7 @@ import com.red.circle.other.app.dto.clientobject.activity.WeekStarHistoryVO;
import com.red.circle.other.app.dto.clientobject.gift.GiftConfigCO;
import com.red.circle.other.app.dto.cmd.activity.WeekStarGiftQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarRankingQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarExchangeCmd;
import com.red.circle.other.inner.enums.activity.WeekStarGiftTypeEnum;
import com.red.circle.other.inner.model.dto.activity.props.ActivityResource;
import com.red.circle.tool.core.collection.CollectionUtils;
@ -40,6 +42,7 @@ public class WeekStarServiceImpl implements WeekStarService {
private final WeekStarHistoryTop1QueryExe weekStarHistoryTop1QueryExe;
private final WeekStarStartEndTimeQueryExe weekStarStartEndTimeQueryExe;
private final WeekStarThisWeeksGiftQueryExe weekStarThisWeeksGiftQueryExe;
private final WeekStarExchangeExe weekStarExchangeExe;
@Override
public WeekStarGiftUserRankCO getGiftRanking(WeekStarRankingQueryCmd cmd) {
@ -92,4 +95,9 @@ public class WeekStarServiceImpl implements WeekStarService {
public List<WeekStarHistoryVO> getHistoryTop1(AppExtCommand cmd) {
return weekStarHistoryTop1QueryExe.execute(cmd);
}
@Override
public Long exchange(WeekStarExchangeCmd cmd) {
return weekStarExchangeExe.execute(cmd);
}
}

View File

@ -0,0 +1,29 @@
package com.red.circle.other.app.dto.cmd.activity;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 周星碎片兑换命令.
*
* @author pengshigang on 2025/9/19
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class WeekStarExchangeCmd extends AppExtCommand {
/**
* 道具组ID.
*/
@NotNull(message = "propsGroupId {not.null}")
private Long propsGroupId;
/**
* 碎片ID.
*/
@NotNull(message = "fragmentsId {not.null}")
private Long fragmentsId;
}

View File

@ -9,6 +9,7 @@ import com.red.circle.other.app.dto.clientobject.activity.WeekStarHistoryVO;
import com.red.circle.other.app.dto.clientobject.gift.GiftConfigCO;
import com.red.circle.other.app.dto.cmd.activity.WeekStarGiftQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarRankingQueryCmd;
import com.red.circle.other.app.dto.cmd.activity.WeekStarExchangeCmd;
import com.red.circle.other.inner.model.dto.activity.props.ActivityResource;
import java.util.List;
@ -41,4 +42,9 @@ public interface WeekStarService {
*/
List<WeekStarHistoryVO> getHistoryTop1(AppExtCommand cmd);
/**
* 碎片兑换.
*/
Long exchange(WeekStarExchangeCmd cmd);
}

View File

@ -35,7 +35,7 @@ public interface FragmentsBackpackService extends BaseService<FragmentsBackpack>
* @param fragmentsIds 碎片ids
* @param quantity 数量
*/
void decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity);
boolean decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity);
/**
* 根据用户id与碎片集合查询用户碎片背包并且数量大于0

View File

@ -54,12 +54,12 @@ public class FragmentsBackpackServiceImpl extends
}
@Override
public void decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
public boolean decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
if (Objects.isNull(userId) || CollectionUtils.isEmpty(fragmentsIds) || quantity <= 0) {
return;
return false;
}
update().set(FragmentsBackpack::getUpdateTime, TimestampUtils.now())
return update().set(FragmentsBackpack::getUpdateTime, TimestampUtils.now())
.setSql("quantity=quantity-" + quantity)
.in(FragmentsBackpack::getFragmentsId, fragmentsIds)
.eq(FragmentsBackpack::getUserId, userId)

View File

@ -12,6 +12,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static com.red.circle.framework.core.response.CommonErrorCode.OPERATING_FAILURE;
/**
* 碎片服务.
*
@ -35,8 +37,9 @@ public class FragmentsBackpackClientEndpoint implements FragmentsBackpackClientA
@Override
public ResultResponse<Void> decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
fragmentsBackpackClientService.decrFragments(userId, fragmentsIds, quantity);
return ResultResponse.success();
return fragmentsBackpackClientService.decrFragments(userId, fragmentsIds, quantity) ?
ResultResponse.success() :
ResultResponse.failure(OPERATING_FAILURE);
}
@Override

View File

@ -29,7 +29,7 @@ public interface FragmentsBackpackClientService {
* @param fragmentsIds 碎片ids
* @param quantity 数量
*/
void decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity);
boolean decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity);
/**
* 根据用户id与碎片集合查询用户碎片背包并且数量大于0

View File

@ -29,8 +29,8 @@ public class FragmentsBackpackClientServiceImpl implements FragmentsBackpackClie
}
@Override
public void decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
fragmentsBackpackService.decrFragments(userId, fragmentsIds, quantity);
public boolean decrFragments(Long userId, Set<Long> fragmentsIds, Integer quantity) {
return fragmentsBackpackService.decrFragments(userId, fragmentsIds, quantity);
}
@Override