fix: unbind coin seller from actual manager relation

This commit is contained in:
zhx 2026-07-17 19:55:04 +08:00
parent f49e897431
commit c064ae8568
12 changed files with 194 additions and 17 deletions

View File

@ -7,11 +7,14 @@ import com.red.circle.other.inner.model.cmd.sys.AppUserDetailsQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthResourceCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorChangeStatusCmd;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.dto.sys.AdministratorDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorAuthResourceDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorInfoDTO;
import com.red.circle.other.inner.model.dto.team.AdminRechargeAgentRelationDTO;
import java.util.List;
import java.util.Set;
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.RequestBody;
@ -35,6 +38,21 @@ public interface AdministratorClientApi {
@GetMapping("/getByUserId")
ResultResponse<AdministratorDTO> getByUserId(@RequestParam("userId") Long userId);
/**
* 获取充值代理当前绑定的管理员关系.
*/
@GetMapping("/getRechargeAgentRelation")
ResultResponse<AdminRechargeAgentRelationDTO> getRechargeAgentRelation(
@RequestParam("sysOrigin") String sysOrigin,
@RequestParam("userId") Long userId);
/**
* 后台解绑充值代理当前绑定的管理员.
*/
@PostMapping("/unbindRechargeAgentRelation")
ResultResponse<Void> unbindRechargeAgentRelation(
@RequestBody @Validated AdminRechargeAgentRelationUnbindCmd cmd);
/**
* 是否可用.
*

View File

@ -0,0 +1,32 @@
package com.red.circle.other.inner.model.cmd.team;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serial;
import java.io.Serializable;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 后台解绑管理员与充值代理关系.
*/
@Data
@Accessors(chain = true)
public class AdminRechargeAgentRelationUnbindCmd implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull
@JsonSerialize(using = ToStringSerializer.class)
private Long relationId;
@NotBlank
private String sysOrigin;
@NotNull
@JsonSerialize(using = ToStringSerializer.class)
private Long childUserId;
}

View File

@ -0,0 +1,33 @@
package com.red.circle.other.inner.model.dto.team;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import java.io.Serial;
import java.io.Serializable;
import java.sql.Timestamp;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 管理员与充值代理关系.
*/
@Data
@Accessors(chain = true)
public class AdminRechargeAgentRelationDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@JsonSerialize(using = ToStringSerializer.class)
private Long relationId;
private String sysOrigin;
@JsonSerialize(using = ToStringSerializer.class)
private Long adminUserId;
@JsonSerialize(using = ToStringSerializer.class)
private Long userId;
private Timestamp createTime;
}

View File

@ -13,9 +13,9 @@ import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.web.controller.BaseController;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.cmd.user.UserFreightBalanceCmd;
import com.red.circle.wallet.inner.model.cmd.UpdateFreightBalanceInfoCmd;
import com.red.circle.wallet.inner.model.cmd.FreightSubSellerUnbindCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalancePageQryCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalanceRunningWaterExportQryCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalanceRunningWaterPageQryCmd;
@ -198,7 +198,7 @@ public class UserFreightRestController extends BaseController {
@OpsOperationReqLog("货运代理-解绑币商上级")
@PostMapping("/sub-seller-parent/unbind")
public void unbindFreightSubSellerParent(
@RequestBody @Validated FreightSubSellerUnbindCmd cmd) {
@RequestBody @Validated AdminRechargeAgentRelationUnbindCmd cmd) {
userFreightService.unbindFreightSubSellerParent(cmd);
}

View File

@ -16,6 +16,7 @@ import com.red.circle.order.inner.endpoint.UserFreightRechargeRecordClient;
import com.red.circle.other.inner.asserts.ImErrorCode;
import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient;
import com.red.circle.other.inner.endpoint.material.props.BadgeSourceClient;
import com.red.circle.other.inner.endpoint.sys.AdministratorClient;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.LocalDateTimeUtils;
@ -26,13 +27,14 @@ import com.red.circle.other.inner.endpoint.user.region.UserRegionClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.user.UserFreightBalanceCmd;
import com.red.circle.other.inner.model.cmd.user.UserRegionConfigMapCmd;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.dto.team.AdminRechargeAgentRelationDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.other.inner.model.dto.user.reigon.RegionConfigDTO;
import com.red.circle.wallet.inner.endpoint.freight.FreightGoldClient;
import com.red.circle.wallet.inner.error.WalletErrorCode;
import com.red.circle.wallet.inner.model.cmd.AddFreightBalanceRunningWaterCmd;
import com.red.circle.wallet.inner.model.cmd.FreightAgentReviewCmd;
import com.red.circle.wallet.inner.model.cmd.FreightSubSellerUnbindCmd;
import com.red.circle.wallet.inner.model.cmd.UpdateFreightBalanceInfoCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalancePageQryCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalanceRunningWaterExportQryCmd;
@ -41,7 +43,6 @@ import com.red.circle.wallet.inner.model.cmd.UserFreightSellerCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightSellerRunningWaterPageQryCmd;
import com.red.circle.wallet.inner.model.dto.UserFreightBalanceDTO;
import com.red.circle.wallet.inner.model.dto.UserFreightBalanceRunningWaterDTO;
import com.red.circle.wallet.inner.model.dto.FreightSubSellerRelationDTO;
import com.red.circle.wallet.inner.model.enums.FreightBalanceOrigin;
import java.math.BigDecimal;
import java.math.RoundingMode;
@ -73,6 +74,7 @@ public class UserFreightBalanceServiceImpl implements
private final RedisService redisService;
private final UserRegionClient userRegionClient;
private final UserProfileClient userProfileClient;
private final AdministratorClient administratorClient;
private final FreightGoldClient freightGoldClient;
private final BadgeSourceClient badgeSourceClient;
private final WalletAppConvertor walletAppConvertor;
@ -552,27 +554,26 @@ public class UserFreightBalanceServiceImpl implements
@Override
public FreightSubSellerParentCO getFreightSubSellerParent(String sysOrigin, Long childUserId) {
FreightSubSellerRelationDTO relation = ResponseAssert.requiredSuccess(
freightGoldClient.getFreightSubSellerRelation(sysOrigin, childUserId));
AdminRechargeAgentRelationDTO relation = ResponseAssert.requiredSuccess(
administratorClient.getRechargeAgentRelation(sysOrigin, childUserId));
if (Objects.isNull(relation)) {
return null;
}
UserProfileDTO parentUser = ResponseAssert.requiredSuccess(
userProfileClient.getByUserId(relation.getParentUserId()));
userProfileClient.getByUserId(relation.getAdminUserId()));
return new FreightSubSellerParentCO()
.setRelationId(relation.getRelationId())
.setSysOrigin(relation.getSysOrigin())
.setParentFreightId(relation.getParentFreightId())
.setParentUserId(relation.getParentUserId())
.setChildUserId(relation.getChildUserId())
.setParentUserId(relation.getAdminUserId())
.setChildUserId(relation.getUserId())
.setCreateTime(relation.getCreateTime())
.setParentUserBaseInfo(parentUser);
}
@Override
public void unbindFreightSubSellerParent(FreightSubSellerUnbindCmd cmd) {
ResponseAssert.requiredSuccess(freightGoldClient.unbindFreightSubSellerRelation(cmd));
public void unbindFreightSubSellerParent(AdminRechargeAgentRelationUnbindCmd cmd) {
ResponseAssert.requiredSuccess(administratorClient.unbindRechargeAgentRelation(cmd));
}
}

View File

@ -10,7 +10,7 @@ import lombok.Data;
import lombok.experimental.Accessors;
/**
* 后台展示的 coin seller 上级绑定信息.
* 后台展示的充值代理/币商上级经理绑定信息.
*/
@Data
@Accessors(chain = true)

View File

@ -4,9 +4,9 @@ import com.red.circle.console.app.dto.clienobject.user.UserFreightBalanceCO;
import com.red.circle.console.app.dto.clienobject.user.UserFreightBalanceRunningWaterCO;
import com.red.circle.console.app.dto.clienobject.user.FreightSubSellerParentCO;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.cmd.user.UserFreightBalanceCmd;
import com.red.circle.wallet.inner.model.cmd.UpdateFreightBalanceInfoCmd;
import com.red.circle.wallet.inner.model.cmd.FreightSubSellerUnbindCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalancePageQryCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalanceRunningWaterExportQryCmd;
import com.red.circle.wallet.inner.model.cmd.UserFreightBalanceRunningWaterPageQryCmd;
@ -121,12 +121,12 @@ public interface UserFreightService {
void updateFreightBalanceInfo(UpdateFreightBalanceInfoCmd cmd);
/**
* 查询 coin seller 当前绑定的上级超级经销商.
* 查询充值代理/币商当前绑定的上级经理.
*/
FreightSubSellerParentCO getFreightSubSellerParent(String sysOrigin, Long childUserId);
/**
* 解绑 coin seller 当前的上级超级经销商.
* 解绑充值代理/币商当前绑定的上级经理.
*/
void unbindFreightSubSellerParent(FreightSubSellerUnbindCmd cmd);
void unbindFreightSubSellerParent(AdminRechargeAgentRelationUnbindCmd cmd);
}

View File

@ -22,6 +22,11 @@ public interface AdminRechargeAgentRelationService extends BaseService<AdminRech
*/
List<AdminRechargeAgentRelation> getByUserId(Long userId);
/**
* 根据平台和充值代理用户ID查询当前关系.
*/
AdminRechargeAgentRelation getByUserId(String sysOrigin, Long userId);
/**
* 检查用户是否是充值代理.
*
@ -37,6 +42,11 @@ public interface AdminRechargeAgentRelationService extends BaseService<AdminRech
*/
void add(AdminRechargeAgentRelation relation);
/**
* 精确删除指定关系避免管理员查看后发生换绑时误删新关系.
*/
boolean removeBinding(Long relationId, String sysOrigin, Long userId);
/**
* 分页查询管理员下的充值代理.
*

View File

@ -27,6 +27,15 @@ public class AdminRechargeAgentRelationServiceImpl extends
.eq(AdminRechargeAgentRelation::getUserId, userId));
}
@Override
public AdminRechargeAgentRelation getByUserId(String sysOrigin, Long userId) {
return query()
.eq(AdminRechargeAgentRelation::getSysOrigin, sysOrigin)
.eq(AdminRechargeAgentRelation::getUserId, userId)
.last("LIMIT 1")
.getOne();
}
@Override
public boolean checkRechargeAgent(Long userId) {
return count(new LambdaQueryWrapper<AdminRechargeAgentRelation>()
@ -38,6 +47,15 @@ public class AdminRechargeAgentRelationServiceImpl extends
save(relation);
}
@Override
public boolean removeBinding(Long relationId, String sysOrigin, Long userId) {
// 关系ID平台和充值代理必须同时匹配防止并发换绑后误删新上级关系.
return remove(new LambdaQueryWrapper<AdminRechargeAgentRelation>()
.eq(AdminRechargeAgentRelation::getId, relationId)
.eq(AdminRechargeAgentRelation::getSysOrigin, sysOrigin)
.eq(AdminRechargeAgentRelation::getUserId, userId));
}
@Override
public IPage<AdminRechargeAgentRelation> pageRechargeAgentByAdmin(Long adminUserId, Page<AdminRechargeAgentRelation> page) {
return page(page, new LambdaQueryWrapper<AdminRechargeAgentRelation>()

View File

@ -9,9 +9,11 @@ import com.red.circle.other.inner.model.cmd.sys.AppUserDetailsQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthResourceCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorChangeStatusCmd;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.dto.sys.AdministratorDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorAuthResourceDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorInfoDTO;
import com.red.circle.other.inner.model.dto.team.AdminRechargeAgentRelationDTO;
import java.util.List;
import java.util.Set;
import lombok.RequiredArgsConstructor;
@ -38,6 +40,20 @@ public class AdministratorClientEndpoint implements AdministratorClientApi {
return ResultResponse.success(administratorClientService.getByUserId(userId));
}
@Override
public ResultResponse<AdminRechargeAgentRelationDTO> getRechargeAgentRelation(String sysOrigin,
Long userId) {
return ResultResponse.success(
administratorClientService.getRechargeAgentRelation(sysOrigin, userId));
}
@Override
public ResultResponse<Void> unbindRechargeAgentRelation(
AdminRechargeAgentRelationUnbindCmd cmd) {
administratorClientService.unbindRechargeAgentRelation(cmd);
return ResultResponse.success();
}
@Override
public ResultResponse<Boolean> existsAvailable(Set<Long> userIds) {
return ResultResponse.success(administratorClientService.existsAvailable(userIds));

View File

@ -6,9 +6,11 @@ import com.red.circle.other.inner.model.cmd.sys.AppUserDetailsQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthResourceCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorChangeStatusCmd;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.dto.sys.AdministratorDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorAuthResourceDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorInfoDTO;
import com.red.circle.other.inner.model.dto.team.AdminRechargeAgentRelationDTO;
import java.util.List;
import java.util.Set;
@ -24,6 +26,16 @@ public interface AdministratorClientService {
*/
AdministratorDTO getByUserId(Long userId);
/**
* 获取充值代理当前绑定的管理员关系.
*/
AdminRechargeAgentRelationDTO getRechargeAgentRelation(String sysOrigin, Long userId);
/**
* 后台解绑充值代理当前绑定的管理员.
*/
void unbindRechargeAgentRelation(AdminRechargeAgentRelationUnbindCmd cmd);
/**
* 是否可用.
*

View File

@ -3,6 +3,7 @@ package com.red.circle.other.app.inner.service.sys.impl;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.mq.business.model.event.BadgeOperateEvent;
import com.red.circle.mq.rocket.business.producer.UserMqMessageService;
import com.red.circle.other.app.inner.convertor.sys.AdministratorInnerConvertor;
@ -12,9 +13,11 @@ import com.red.circle.other.app.inner.service.sys.BadgeConfigClientService;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.rds.entity.sys.Administrator;
import com.red.circle.other.infra.database.rds.entity.sys.AdministratorAuth;
import com.red.circle.other.infra.database.rds.entity.team.AdminRechargeAgentRelation;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorAuthResourceService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorAuthService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.infra.database.rds.service.team.AdminRechargeAgentRelationService;
import com.red.circle.other.inner.enums.material.BadgeKeyEnum;
import com.red.circle.other.inner.enums.sys.appmanager.RoomRolesEnum;
import com.red.circle.other.inner.model.cmd.sys.AddSysAdministratorCmd;
@ -22,9 +25,11 @@ import com.red.circle.other.inner.model.cmd.sys.AppUserDetailsQryCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorAuthResourceCmd;
import com.red.circle.other.inner.model.cmd.sys.SysAdministratorChangeStatusCmd;
import com.red.circle.other.inner.model.cmd.team.AdminRechargeAgentRelationUnbindCmd;
import com.red.circle.other.inner.model.dto.sys.AdministratorDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorAuthResourceDTO;
import com.red.circle.other.inner.model.dto.sys.SysAdministratorInfoDTO;
import com.red.circle.other.inner.model.dto.team.AdminRechargeAgentRelationDTO;
import com.red.circle.tool.core.text.StringUtils;
import java.util.*;
@ -42,7 +47,9 @@ import org.springframework.stereotype.Service;
public class AdministratorClientServiceImpl implements AdministratorClientService {
private final UserProfileGateway userProfileGateway;
private final RedisService redisService;
private final AdministratorService administratorService;
private final AdminRechargeAgentRelationService adminRechargeAgentRelationService;
private final AdministratorAuthService administratorAuthService;
private final BadgeConfigClientService badgeConfigClientService;
private final BadgeBackpackClientService badgeBackpackClientService;
@ -57,6 +64,36 @@ public class AdministratorClientServiceImpl implements AdministratorClientServic
);
}
@Override
public AdminRechargeAgentRelationDTO getRechargeAgentRelation(String sysOrigin, Long userId) {
AdminRechargeAgentRelation relation =
adminRechargeAgentRelationService.getByUserId(sysOrigin, userId);
if (Objects.isNull(relation)) {
return null;
}
return new AdminRechargeAgentRelationDTO()
.setRelationId(relation.getId())
.setSysOrigin(relation.getSysOrigin())
.setAdminUserId(relation.getAdminUserId())
.setUserId(relation.getUserId())
.setCreateTime(java.sql.Timestamp.valueOf(relation.getCreateTime()));
}
@Override
public void unbindRechargeAgentRelation(AdminRechargeAgentRelationUnbindCmd cmd) {
AdminRechargeAgentRelation relation =
adminRechargeAgentRelationService.getByUserId(cmd.getSysOrigin(), cmd.getChildUserId());
ResponseAssert.isTrue(CommonErrorCode.NOT_FOUND_RECORD_INFO,
Objects.nonNull(relation) && Objects.equals(relation.getId(), cmd.getRelationId()));
ResponseAssert.isTrue(CommonErrorCode.DELETE_FAILURE,
adminRechargeAgentRelationService.removeBinding(cmd.getRelationId(), cmd.getSysOrigin(),
cmd.getChildUserId()));
// H5 管理员团队汇总缓存包含充值代理数量解绑成功后立即失效旧上级缓存.
redisService.delete("bdteam:summary:" + relation.getAdminUserId());
}
@Override
public boolean existsAvailable(Set<Long> userIds) {
return administratorService.existsAvailable(userIds);