|
@@ -5,6 +5,7 @@ import cn.iocoder.byzs.framework.common.pojo.PageParam;
|
|
|
import cn.iocoder.byzs.framework.common.pojo.PageResult;
|
|
import cn.iocoder.byzs.framework.common.pojo.PageResult;
|
|
|
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
|
|
import cn.iocoder.byzs.framework.common.util.object.BeanUtils;
|
|
|
import cn.iocoder.byzs.framework.common.util.string.StrUtils;
|
|
import cn.iocoder.byzs.framework.common.util.string.StrUtils;
|
|
|
|
|
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
import cn.iocoder.byzs.framework.tenant.core.util.TenantUtils;
|
|
import cn.iocoder.byzs.framework.tenant.core.util.TenantUtils;
|
|
|
import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodePageReqVO;
|
|
import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodePageReqVO;
|
|
|
import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeRespVO;
|
|
import cn.iocoder.byzs.module.system.controller.admin.invitecode.vo.InviteCodeRespVO;
|
|
@@ -17,16 +18,20 @@ import cn.iocoder.byzs.module.system.dal.mysql.invitecode.InviteCodeMapper;
|
|
|
import cn.iocoder.byzs.module.system.dal.mysql.permission.RoleMapper;
|
|
import cn.iocoder.byzs.module.system.dal.mysql.permission.RoleMapper;
|
|
|
import cn.iocoder.byzs.module.system.dal.mysql.tenant.TenantMapper;
|
|
import cn.iocoder.byzs.module.system.dal.mysql.tenant.TenantMapper;
|
|
|
import cn.iocoder.byzs.module.system.dal.mysql.user.AdminUserMapper;
|
|
import cn.iocoder.byzs.module.system.dal.mysql.user.AdminUserMapper;
|
|
|
|
|
+import cn.iocoder.byzs.module.system.service.sms.SmsSendService;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import jakarta.annotation.Resource;
|
|
import jakarta.annotation.Resource;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
import static cn.iocoder.byzs.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
+import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.INVITE_CODE_DUPLICATE;
|
|
|
import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.INVITE_CODE_NOT_EXISTS;
|
|
import static cn.iocoder.byzs.module.system.enums.ErrorCodeConstants.INVITE_CODE_NOT_EXISTS;
|
|
|
|
|
+import static cn.iocoder.byzs.module.system.enums.sms.SmsSceneEnum.ALY_MEMBER_PUSH_INVITATION_CODE;
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 邀请码 Service 实现类
|
|
* 邀请码 Service 实现类
|
|
@@ -49,6 +54,9 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private AdminUserMapper userMapper;
|
|
private AdminUserMapper userMapper;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private SmsSendService smsSendService;
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
public Long createInviteCode(InviteCodeSaveReqVO createReqVO) {
|
|
public Long createInviteCode(InviteCodeSaveReqVO createReqVO) {
|
|
|
// 批量生成邀请码
|
|
// 批量生成邀请码
|
|
@@ -60,25 +68,40 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
for (int i = 0; i < batchCount; i++) {
|
|
for (int i = 0; i < batchCount; i++) {
|
|
|
InviteCodeDO inviteCode = BeanUtils.toBean(createReqVO, InviteCodeDO.class);
|
|
InviteCodeDO inviteCode = BeanUtils.toBean(createReqVO, InviteCodeDO.class);
|
|
|
// 生成随机邀请码
|
|
// 生成随机邀请码
|
|
|
- String randomCode = generateRandomCode(10);
|
|
|
|
|
- // 如果有前缀,则拼接前缀
|
|
|
|
|
- if (createReqVO.getCode() != null && !createReqVO.getCode().isEmpty()) {
|
|
|
|
|
- inviteCode.setCode(createReqVO.getCode() + randomCode);
|
|
|
|
|
- } else {
|
|
|
|
|
- inviteCode.setCode(randomCode);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ String randomCode;
|
|
|
|
|
+ String finalCode;
|
|
|
|
|
+ do {
|
|
|
|
|
+ randomCode = generateRandomCode(10);
|
|
|
|
|
+ // 如果有前缀,则拼接前缀
|
|
|
|
|
+ if (createReqVO.getCode() != null && !createReqVO.getCode().isEmpty()) {
|
|
|
|
|
+ finalCode = createReqVO.getCode() + randomCode;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ finalCode = randomCode;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 校验邀请码是否已存在
|
|
|
|
|
+ } while (isInviteCodeExists(finalCode));
|
|
|
|
|
+ inviteCode.setCode(finalCode);
|
|
|
inviteCodeList.add(inviteCode);
|
|
inviteCodeList.add(inviteCode);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 批量插入
|
|
// 批量插入
|
|
|
inviteCodeMapper.insertBatch(inviteCodeList);
|
|
inviteCodeMapper.insertBatch(inviteCodeList);
|
|
|
|
|
|
|
|
|
|
+ // 如果需要发送短信通知
|
|
|
|
|
+ if (Boolean.TRUE.equals(createReqVO.getSendSms())) {
|
|
|
|
|
+ for (InviteCodeDO inviteCode : inviteCodeList) {
|
|
|
|
|
+ if (inviteCode.getOnlyPhone() != null && !inviteCode.getOnlyPhone().isEmpty()) {
|
|
|
|
|
+ sendInviteCodeSms(inviteCode);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 返回第一个生成的邀请码ID
|
|
// 返回第一个生成的邀请码ID
|
|
|
return inviteCodeList.get(0).getId();
|
|
return inviteCodeList.get(0).getId();
|
|
|
}
|
|
}
|
|
|
// 批量手机号生成邀请码
|
|
// 批量手机号生成邀请码
|
|
|
else if ("batchPhone".equals(createReqVO.getType())) {
|
|
else if ("batchPhone".equals(createReqVO.getType())) {
|
|
|
- List<String> batchPhones = createReqVO.getOnlyPhoneList();
|
|
|
|
|
|
|
+ List<String> batchPhones = createReqVO.getBatchPhones();
|
|
|
|
|
|
|
|
// 生成批量邀请码
|
|
// 生成批量邀请码
|
|
|
List<InviteCodeDO> inviteCodeList = new ArrayList<>(batchPhones.size());
|
|
List<InviteCodeDO> inviteCodeList = new ArrayList<>(batchPhones.size());
|
|
@@ -87,19 +110,32 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
// 设置手机号
|
|
// 设置手机号
|
|
|
inviteCode.setOnlyPhone(phone);
|
|
inviteCode.setOnlyPhone(phone);
|
|
|
// 生成随机邀请码
|
|
// 生成随机邀请码
|
|
|
- String randomCode = generateRandomCode(10);
|
|
|
|
|
- // 如果有前缀,则拼接前缀
|
|
|
|
|
- if (createReqVO.getCode() != null && !createReqVO.getCode().isEmpty()) {
|
|
|
|
|
- inviteCode.setCode(createReqVO.getCode() + randomCode);
|
|
|
|
|
- } else {
|
|
|
|
|
- inviteCode.setCode(randomCode);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ String randomCode;
|
|
|
|
|
+ String finalCode;
|
|
|
|
|
+ do {
|
|
|
|
|
+ randomCode = generateRandomCode(10);
|
|
|
|
|
+ // 如果有前缀,则拼接前缀
|
|
|
|
|
+ if (createReqVO.getCode() != null && !createReqVO.getCode().isEmpty()) {
|
|
|
|
|
+ finalCode = createReqVO.getCode() + randomCode;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ finalCode = randomCode;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 校验邀请码是否已存在
|
|
|
|
|
+ } while (isInviteCodeExists(finalCode));
|
|
|
|
|
+ inviteCode.setCode(finalCode);
|
|
|
inviteCodeList.add(inviteCode);
|
|
inviteCodeList.add(inviteCode);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 批量插入
|
|
// 批量插入
|
|
|
inviteCodeMapper.insertBatch(inviteCodeList);
|
|
inviteCodeMapper.insertBatch(inviteCodeList);
|
|
|
|
|
|
|
|
|
|
+ // 如果需要发送短信通知
|
|
|
|
|
+ if (Boolean.TRUE.equals(createReqVO.getSendSms())) {
|
|
|
|
|
+ for (InviteCodeDO inviteCode : inviteCodeList) {
|
|
|
|
|
+ sendInviteCodeSms(inviteCode);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 返回第一个生成的邀请码ID
|
|
// 返回第一个生成的邀请码ID
|
|
|
return inviteCodeList.get(0).getId();
|
|
return inviteCodeList.get(0).getId();
|
|
|
}
|
|
}
|
|
@@ -108,13 +144,41 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
InviteCodeDO inviteCode = BeanUtils.toBean(createReqVO, InviteCodeDO.class);
|
|
InviteCodeDO inviteCode = BeanUtils.toBean(createReqVO, InviteCodeDO.class);
|
|
|
// 如果没有提供邀请码,则生成一个
|
|
// 如果没有提供邀请码,则生成一个
|
|
|
if (inviteCode.getCode() == null || inviteCode.getCode().isEmpty()) {
|
|
if (inviteCode.getCode() == null || inviteCode.getCode().isEmpty()) {
|
|
|
- inviteCode.setCode(generateRandomCode(10));
|
|
|
|
|
|
|
+ String randomCode;
|
|
|
|
|
+ String finalCode;
|
|
|
|
|
+ do {
|
|
|
|
|
+ randomCode = generateRandomCode(10);
|
|
|
|
|
+ finalCode = randomCode;
|
|
|
|
|
+ // 校验邀请码是否已存在
|
|
|
|
|
+ } while (isInviteCodeExists(finalCode));
|
|
|
|
|
+ inviteCode.setCode(finalCode);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 校验用户提供的邀请码是否已存在
|
|
|
|
|
+ if (isInviteCodeExists(inviteCode.getCode())) {
|
|
|
|
|
+ throw exception(INVITE_CODE_DUPLICATE);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
inviteCodeMapper.insert(inviteCode);
|
|
inviteCodeMapper.insert(inviteCode);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果需要发送短信通知
|
|
|
|
|
+ if (Boolean.TRUE.equals(createReqVO.getSendSms()) && inviteCode.getOnlyPhone() != null && !inviteCode.getOnlyPhone().isEmpty()) {
|
|
|
|
|
+ sendInviteCodeSms(inviteCode);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return inviteCode.getId();
|
|
return inviteCode.getId();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 校验邀请码是否已存在
|
|
|
|
|
+ * @param code 邀请码
|
|
|
|
|
+ * @return 是否存在
|
|
|
|
|
+ */
|
|
|
|
|
+ private boolean isInviteCodeExists(String code) {
|
|
|
|
|
+ return inviteCodeMapper.selectOne(new LambdaQueryWrapperX<InviteCodeDO>()
|
|
|
|
|
+ .eq(InviteCodeDO::getCode, code)) != null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 生成指定长度的随机邀请码
|
|
* 生成指定长度的随机邀请码
|
|
|
* @param length 邀请码长度
|
|
* @param length 邀请码长度
|
|
@@ -251,6 +315,10 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
respVO.setUseUserTenantName(tenantMap.get(inviteCode.getUseUserTenantId()));
|
|
respVO.setUseUserTenantName(tenantMap.get(inviteCode.getUseUserTenantId()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 填充通知状态和通知时间
|
|
|
|
|
+ respVO.setNotifyStatus(inviteCode.getNotifyStatus());
|
|
|
|
|
+ respVO.setNotifyTime(inviteCode.getNotifyTime());
|
|
|
|
|
+
|
|
|
return respVO;
|
|
return respVO;
|
|
|
}).collect(Collectors.toList());
|
|
}).collect(Collectors.toList());
|
|
|
|
|
|
|
@@ -325,4 +393,57 @@ public class InviteCodeServiceImpl implements InviteCodeService {
|
|
|
return new PageResult<>(pagedList, (long) total);
|
|
return new PageResult<>(pagedList, (long) total);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 发送邀请码短信
|
|
|
|
|
+ * @param inviteCode 邀请码对象
|
|
|
|
|
+ */
|
|
|
|
|
+ public void sendInviteCodeSms(InviteCodeDO inviteCode) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 校验手机号是否为空
|
|
|
|
|
+ if (inviteCode.getOnlyPhone() == null || inviteCode.getOnlyPhone().isEmpty()) {
|
|
|
|
|
+ // 手机号为空,不发送短信
|
|
|
|
|
+ inviteCode.setNotifyStatus("2");
|
|
|
|
|
+ inviteCode.setNotifyTime(LocalDateTime.now());
|
|
|
|
|
+ inviteCodeMapper.updateById(inviteCode);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建短信模板参数
|
|
|
|
|
+ Map<String, Object> templateParams = new HashMap<>();
|
|
|
|
|
+ templateParams.put("user", inviteCode.getOnlyPhone());
|
|
|
|
|
+ templateParams.put("code", inviteCode.getCode());
|
|
|
|
|
+
|
|
|
|
|
+ // 发送短信(使用短信模板编码,需要根据实际情况配置)
|
|
|
|
|
+ // 这里假设模板编码为 "invite_code_notify"
|
|
|
|
|
+ smsSendService.sendSingleSmsToAdmin(inviteCode.getOnlyPhone(), null, ALY_MEMBER_PUSH_INVITATION_CODE.getTemplateCode(), templateParams);
|
|
|
|
|
+
|
|
|
|
|
+ // 更新通知状态为成功
|
|
|
|
|
+ inviteCode.setNotifyStatus("1");
|
|
|
|
|
+ inviteCode.setNotifyTime(LocalDateTime.now());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ // 更新通知状态为失败
|
|
|
|
|
+ inviteCode.setNotifyStatus("2");
|
|
|
|
|
+ inviteCode.setNotifyTime(LocalDateTime.now());
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ // 更新邀请码记录
|
|
|
|
|
+ inviteCodeMapper.updateById(inviteCode);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 单独发送邀请码短信
|
|
|
|
|
+ * @param id 邀请码ID
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void sendSmsById(Long id) {
|
|
|
|
|
+ InviteCodeDO inviteCode = inviteCodeMapper.selectById(id);
|
|
|
|
|
+ if (inviteCode == null) {
|
|
|
|
|
+ throw exception(INVITE_CODE_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (inviteCode.getOnlyPhone() == null || inviteCode.getOnlyPhone().isEmpty()) {
|
|
|
|
|
+ throw exception(INVITE_CODE_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ sendInviteCodeSms(inviteCode);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|