XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/service/SubAccountService.java
XuqmGroup 32b0e49e61 docs(deploy): 添加生产环境部署配置示例和部署文档
- 新增 .env.production.example 环境变量配置模板
- 添加 compose.production.yaml Docker Compose 部署配置
- 创建 web.Dockerfile 前端构建部署文件
- 编写详细的 README.md 部署文档,涵盖架构、配置、步骤等内容
- 添加离线推送架构设计文档
- 更新 IM 多平台进度跟踪文档
2026-04-30 09:49:05 +08:00

100 行
4.0 KiB
Java

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;
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;
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) {
this.tenantRepository = tenantRepository;
this.passwordEncoder = passwordEncoder;
this.emailService = emailService;
this.operationLogService = operationLogService;
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;
}
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()
));
}
public String generatePassword() {
byte[] bytes = new byte[9];
random.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
}