新增后台发放道具全功能

This commit is contained in:
tianfeng 2025-11-07 11:29:09 +08:00
parent 931836f2c5
commit c9e791160f
11 changed files with 106 additions and 28 deletions

View File

@ -0,0 +1,16 @@
package com.red.circle.other.inner.endpoint.material.props;
import com.red.circle.other.inner.endpoint.material.props.api.PropCouponClientApi;
import org.springframework.cloud.openfeign.FeignClient;
/**
* 道具券 Client
*
* @author system
* @date 2025-11-07
*/
@FeignClient(name = "propCouponClient", url = "${feign.other.url}" +
PropCouponClientApi.API_PREFIX)
public interface PropCouponClient extends PropCouponClientApi {
}

View File

@ -0,0 +1,24 @@
package com.red.circle.other.inner.endpoint.material.props.api;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 道具券 Client API
*
* @author system
* @date 2025-11-071
*/
public interface PropCouponClientApi {
String API_PREFIX = "/props/coupon/client";
/**
* 后台赠送道具券
*/
@PostMapping("/grant")
ResultResponse<Void> grantCoupons(@RequestBody PropCouponGrantCmd cmd);
}

View File

@ -1,7 +1,6 @@
package com.red.circle.other.app.dto.cmd;
package com.red.circle.other.inner.model.cmd.material;
import com.red.circle.common.business.dto.cmd.AppExtCommand;
import jakarta.validation.constraints.NotBlank;
import com.red.circle.framework.dto.Command;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -16,7 +15,7 @@ import java.util.List;
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PropCouponGrantCmd extends AppExtCommand {
public class PropCouponGrantCmd extends Command {
/**
* 券类型1头像框 2座驾 3VIP 4聊天气泡 5主题 6资料卡 7飘屏 8徽章 9靓号
@ -27,7 +26,7 @@ public class PropCouponGrantCmd extends AppExtCommand {
* 道具ID
*/
@NotNull(message = "道具ID不能为空")
private Long propId;
private String propId;
private String propIcon;
@ -46,7 +45,7 @@ public class PropCouponGrantCmd extends AppExtCommand {
* 接收用户ID列表
*/
@NotNull(message = "接收用户ID列表不能为空")
private List<Long> userIds;
private List<String> userIds;
/**
* 备注

View File

@ -4,6 +4,7 @@ import com.red.circle.console.app.dto.cmd.app.props.PropsGiveUserCmd;
import com.red.circle.console.app.service.app.props.PropsGiveService;
import com.red.circle.console.infra.annotations.OpsOperationReqLog;
import com.red.circle.framework.web.controller.BaseController;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@ -31,4 +32,10 @@ public class PropsGiveRestController extends BaseController {
return propsGiveService.give(cmd);
}
@OpsOperationReqLog(value = "道具赠送-后台赠送道具券")
@PostMapping("/grant-coupon")
public void grantCoupon(@RequestBody @Validated PropCouponGrantCmd cmd) {
propsGiveService.givePropCoupon(cmd);
}
}

View File

@ -10,12 +10,7 @@ import com.red.circle.console.app.service.admin.UserAccountService;
import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.inner.endpoint.live.RoomManagerClient;
import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.PropsBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.PropsCommodityStoreClient;
import com.red.circle.other.inner.endpoint.material.props.PropsNobleVipClient;
import com.red.circle.other.inner.endpoint.material.props.PropsSourceClient;
import com.red.circle.other.inner.endpoint.material.props.RoomThemeBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.*;
import com.red.circle.other.inner.endpoint.user.user.SysUserProfileClient;
import com.red.circle.other.inner.enums.material.BadgeBackpackExpireTypeEnum;
import com.red.circle.other.inner.enums.material.ConsolePropsTypeEnum;
@ -24,6 +19,7 @@ import com.red.circle.other.inner.enums.sys.SysBadgeConfigTypeEnum;
import com.red.circle.other.inner.enums.sys.SysCurrencySendReasonEnum;
import com.red.circle.other.inner.model.cmd.material.GiveBadgeCmd;
import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.inner.model.dto.material.PropsCommodityStoreDTO;
import com.red.circle.other.inner.model.dto.material.PropsResourcesDTO;
import com.red.circle.other.inner.model.dto.material.props.PropsNobleVipAbilityDTO;
@ -74,6 +70,7 @@ public class PropsGiveServiceImpl implements PropsGiveService {
private final RoomThemeBackpackClient roomThemeBackpackClient;
private final PropsCommodityStoreClient propsCommodityStoreClient;
private final UserAccountService userAccountService;
private final PropCouponClient propCouponClient;
@Override
public String give(PropsGiveUserCmd cmd) {
@ -120,6 +117,11 @@ public class PropsGiveServiceImpl implements PropsGiveService {
return null;
}
@Override
public void givePropCoupon(PropCouponGrantCmd cmd) {
propCouponClient.grantCoupons(cmd);
}
private void send(PropsGiveUserCmd cmd) {
String sysOrigin = getUserSysOrigin(cmd.getReceiverId());
ResponseAssert.isFalse(UserErrorCode.USER_INFO_NOT_FOUND, StringUtils.isBlank(sysOrigin));

View File

@ -2,6 +2,7 @@ package com.red.circle.console.app.service.app.props;
import com.red.circle.console.app.dto.cmd.app.props.PropsGiveUserCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
/**
* <p>
@ -18,4 +19,5 @@ public interface PropsGiveService {
*/
String give(PropsGiveUserCmd cmd);
void givePropCoupon(PropCouponGrantCmd cmd);
}

View File

@ -3,7 +3,7 @@ package com.red.circle.other.adapter.app.props;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.dto.clientobject.PropCouponCO;
import com.red.circle.other.app.dto.clientobject.PropCouponRecordCO;
import com.red.circle.other.app.dto.cmd.PropCouponGrantCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.app.dto.cmd.PropCouponQueryCmd;
import com.red.circle.other.app.dto.cmd.PropCouponSendCmd;
import com.red.circle.other.app.dto.cmd.PropCouponUseCmd;

View File

@ -4,19 +4,15 @@ import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateCustomizeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.dto.cmd.PropCouponGrantCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.domain.gateway.PropCouponGateway;
import com.red.circle.other.domain.propcoupon.PropCoupon;
import com.red.circle.other.domain.propcoupon.PropCouponSource;
import com.red.circle.other.domain.propcoupon.PropCouponStatus;
import com.red.circle.other.domain.propcoupon.PropCouponType;
import com.red.circle.other.infra.database.rds.entity.props.PropsCommodityStore;
import com.red.circle.other.infra.database.rds.service.props.PropsCommodityStoreService;
import com.red.circle.other.inner.asserts.OtherErrorCode;
import com.red.circle.other.inner.endpoint.material.props.PropsCommodityStoreClient;
import com.red.circle.other.inner.endpoint.material.props.PropsSourceClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.dto.material.PropsCommodityStoreDTO;
import com.red.circle.other.inner.model.dto.material.PropsResourcesDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
@ -26,10 +22,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -47,7 +40,6 @@ public class PropCouponGrantCmdExe {
private final UserProfileClient userProfileClient;
private final OfficialNoticeClient officialNoticeClient;
private final PropsSourceClient propsSourceClient;
private final PropsCommodityStoreService propsCommodityStoreService;
/**
* 执行后台赠送道具券
@ -58,11 +50,12 @@ public class PropCouponGrantCmdExe {
validateParams(cmd);
// 2. 校验用户是否存在
Set<Long> userIds = Set.copyOf(cmd.getUserIds());
Set<Long> userIds = cmd.getUserIds().stream().map(Long::parseLong).collect(Collectors.toSet());
Map<Long, UserProfileDTO> userMap = validateUsers(userIds);
PropsResourcesDTO propsResourcesDTO = ResponseAssert.requiredSuccess(
propsSourceClient.getById(cmd.getPropId()));
propsSourceClient.getById(Long.parseLong(cmd.getPropId())));
ResponseAssert.notNull(OtherErrorCode.PROP_COUPON_PROP_NOT_FOUND, propsResourcesDTO);
PropCouponType couponType = PropCouponType.getByName(propsResourcesDTO.getType());
@ -127,7 +120,7 @@ public class PropCouponGrantCmdExe {
propCoupon.setCouponNo(generateCouponNo());
propCoupon.setUserId(userId);
propCoupon.setCouponType(couponType);
propCoupon.setPropId(cmd.getPropId());
propCoupon.setPropId(Long.parseLong(cmd.getPropId()));
propCoupon.setPropIcon(cmd.getPropIcon());
propCoupon.setPropName(displayPropName);
propCoupon.setValidDays(cmd.getValidDays());

View File

@ -8,7 +8,7 @@ import com.red.circle.other.app.command.propcoupon.query.PropCouponListQryExe;
import com.red.circle.other.app.command.propcoupon.query.PropCouponRecordQryExe;
import com.red.circle.other.app.dto.clientobject.PropCouponCO;
import com.red.circle.other.app.dto.clientobject.PropCouponRecordCO;
import com.red.circle.other.app.dto.cmd.PropCouponGrantCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.app.dto.cmd.PropCouponQueryCmd;
import com.red.circle.other.app.dto.cmd.PropCouponSendCmd;
import com.red.circle.other.app.dto.cmd.PropCouponUseCmd;

View File

@ -3,7 +3,7 @@ package com.red.circle.other.app.service;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.dto.clientobject.PropCouponCO;
import com.red.circle.other.app.dto.clientobject.PropCouponRecordCO;
import com.red.circle.other.app.dto.cmd.PropCouponGrantCmd;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.app.dto.cmd.PropCouponQueryCmd;
import com.red.circle.other.app.dto.cmd.PropCouponSendCmd;
import com.red.circle.other.app.dto.cmd.PropCouponUseCmd;

View File

@ -0,0 +1,35 @@
package com.red.circle.other.app.inner.endpoint.material.props;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.model.cmd.material.PropCouponGrantCmd;
import com.red.circle.other.app.service.PropCouponService;
import com.red.circle.other.inner.endpoint.material.props.api.PropCouponClientApi;
import com.red.circle.other.inner.endpoint.material.props.api.PropsRedPacketSkinClientApi;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 道具券内部端点
*
* @author system
* @date 2025-11-07
*/
@Validated
@RestController
@RequestMapping(value = PropCouponClientApi.API_PREFIX, produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class PropCouponClientEndpoint implements PropCouponClientApi {
private final PropCouponService propCouponService;
@Override
public ResultResponse<Void> grantCoupons(PropCouponGrantCmd cmd) {
propCouponService.grantCoupons(cmd);
return ResultResponse.success();
}
}