XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/service/SubAccountService.java

100 行
4.0 KiB
Java

2026-04-21 22:07:29 +08:00
package com.xuqm.tenant.service;
import com.xuqm.common.exception.BusinessException;
import com.xuqm.tenant.dto.CreateSubAccountRequest;
import com.xuqm.tenant.entity.TenantEntity;
import com.xuqm.tenant.repository.TenantRepository;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Map;
2026-04-21 22:07:29 +08:00
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Service
public class SubAccountService {
private final TenantRepository tenantRepository;
private final PasswordEncoder passwordEncoder;
private final EmailService emailService;
private final OperationLogService operationLogService;
2026-04-21 22:07:29 +08:00
private final StringRedisTemplate redis;
private static final String SUB_VERIFY_PREFIX = "sub_verified:";
private static final SecureRandom random = new SecureRandom();
public SubAccountService(TenantRepository tenantRepository, PasswordEncoder passwordEncoder,
EmailService emailService, OperationLogService operationLogService,
StringRedisTemplate redis) {
2026-04-21 22:07:29 +08:00
this.tenantRepository = tenantRepository;
this.passwordEncoder = passwordEncoder;
this.emailService = emailService;
this.operationLogService = operationLogService;
2026-04-21 22:07:29 +08:00
this.redis = redis;
}
public boolean isEmailVerifiedInSession(String tenantId) {
return Boolean.TRUE.toString().equals(redis.opsForValue().get(SUB_VERIFY_PREFIX + tenantId));
}
public void verifyEmail(String tenantId, String email, String code) {
emailService.verify(email, code, "SUB_ACCOUNT");
redis.opsForValue().set(SUB_VERIFY_PREFIX + tenantId, Boolean.TRUE.toString(), 24, TimeUnit.HOURS);
}
public TenantEntity create(String parentId, CreateSubAccountRequest req) {
if (tenantRepository.existsByUsername(req.username())) {
throw new BusinessException("用户名已存在");
}
TenantEntity sub = new TenantEntity();
sub.setId(UUID.randomUUID().toString());
sub.setUsername(req.username());
sub.setPassword(passwordEncoder.encode(req.password()));
sub.setEmail(req.email() != null ? req.email() : "");
sub.setNickname(req.nickname());
sub.setPhone(req.phone());
sub.setType(TenantEntity.Type.SUB);
sub.setStatus(TenantEntity.Status.ACTIVE);
sub.setParentId(parentId);
sub.setCreatedAt(LocalDateTime.now());
TenantEntity saved = tenantRepository.save(sub);
operationLogService.record(parentId, "SUB_ACCOUNT", "SUB_ACCOUNT", saved.getId(), "CREATE_SUB_ACCOUNT", Map.of(
"username", saved.getUsername(),
"nickname", saved.getNickname(),
"email", saved.getEmail()
));
return saved;
2026-04-21 22:07:29 +08:00
}
public List<TenantEntity> listByParent(String parentId) {
return tenantRepository.findByParentId(parentId);
}
public void disable(String subId, String parentId) {
TenantEntity sub = tenantRepository.findById(subId)
.orElseThrow(() -> new BusinessException(404, "子账号不存在"));
if (!parentId.equals(sub.getParentId())) {
throw new BusinessException(403, "无权操作");
}
sub.setStatus(TenantEntity.Status.DISABLED);
tenantRepository.save(sub);
operationLogService.record(parentId, "SUB_ACCOUNT", "SUB_ACCOUNT", sub.getId(), "DISABLE_SUB_ACCOUNT", Map.of(
"username", sub.getUsername(),
"nickname", sub.getNickname(),
"email", sub.getEmail()
));
2026-04-21 22:07:29 +08:00
}
public String generatePassword() {
byte[] bytes = new byte[9];
random.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
}