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

184 行
8.3 KiB
Java

2026-04-21 22:07:29 +08:00
package com.xuqm.tenant.service;
import com.xuqm.common.security.JwtUtil;
import com.xuqm.tenant.entity.AppEntity;
import com.xuqm.tenant.entity.FeatureServiceEntity;
2026-04-21 22:07:29 +08:00
import com.xuqm.tenant.entity.OpsAdminEntity;
import com.xuqm.tenant.entity.OperationLogEntity;
import com.xuqm.tenant.entity.ServiceActivationRequestEntity;
2026-04-21 22:07:29 +08:00
import com.xuqm.tenant.entity.TenantEntity;
import com.xuqm.tenant.repository.AppRepository;
import com.xuqm.tenant.repository.FeatureServiceRepository;
2026-04-21 22:07:29 +08:00
import com.xuqm.tenant.repository.OpsAdminRepository;
import com.xuqm.tenant.repository.OperationLogRepository;
import com.xuqm.tenant.repository.ServiceActivationRequestRepository;
2026-04-21 22:07:29 +08:00
import com.xuqm.tenant.repository.TenantRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
2026-04-21 22:07:29 +08:00
import java.util.Map;
import java.util.UUID;
@Service
public class OpsService {
private final TenantRepository tenantRepository;
private final AppRepository appRepository;
private final FeatureServiceRepository featureServiceRepository;
2026-04-21 22:07:29 +08:00
private final OpsAdminRepository opsAdminRepository;
private final ServiceActivationRequestRepository requestRepository;
private final OperationLogRepository operationLogRepository;
2026-04-21 22:07:29 +08:00
private final PasswordEncoder passwordEncoder;
private final JwtUtil jwtUtil;
public OpsService(TenantRepository tenantRepository, AppRepository appRepository,
FeatureServiceRepository featureServiceRepository,
OpsAdminRepository opsAdminRepository,
ServiceActivationRequestRepository requestRepository,
OperationLogRepository operationLogRepository,
PasswordEncoder passwordEncoder, JwtUtil jwtUtil) {
2026-04-21 22:07:29 +08:00
this.tenantRepository = tenantRepository;
this.appRepository = appRepository;
this.featureServiceRepository = featureServiceRepository;
2026-04-21 22:07:29 +08:00
this.opsAdminRepository = opsAdminRepository;
this.requestRepository = requestRepository;
this.operationLogRepository = operationLogRepository;
2026-04-21 22:07:29 +08:00
this.passwordEncoder = passwordEncoder;
this.jwtUtil = jwtUtil;
}
public String login(String username, String password) {
OpsAdminEntity admin = opsAdminRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("用户名或密码错误"));
if (!passwordEncoder.matches(password, admin.getPassword())) {
throw new IllegalArgumentException("用户名或密码错误");
}
return jwtUtil.generate(admin.getId(), Map.of("username", username, "role", "OPS"));
}
public Page<TenantEntity> listTenants(String keyword, int page, int size) {
return tenantRepository.searchTenants(
keyword,
PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))
);
}
public Map<String, Object> getTenantDetail(String tenantId) {
TenantEntity tenant = tenantRepository.findById(tenantId)
.orElseThrow(() -> new IllegalArgumentException("租户不存在"));
List<AppEntity> apps = appRepository.findByTenantId(tenantId);
long subAccountCount = tenantRepository.countByParentId(tenantId);
long activeServiceCount = apps.stream()
.flatMap(app -> featureServiceRepository.findByAppId(app.getId()).stream())
.filter(FeatureServiceEntity::isEnabled)
.count();
Map<String, Object> result = new LinkedHashMap<>();
result.put("id", tenant.getId());
result.put("username", tenant.getUsername());
result.put("nickname", tenant.getNickname());
result.put("email", tenant.getEmail());
result.put("phone", tenant.getPhone());
result.put("type", tenant.getType());
result.put("status", tenant.getStatus());
result.put("parentId", tenant.getParentId());
result.put("createdAt", tenant.getCreatedAt());
result.put("apps", apps);
result.put("appCount", apps.size());
result.put("subAccountCount", subAccountCount);
result.put("activeServiceCount", activeServiceCount);
return result;
}
public List<AppEntity> listTenantApps(String tenantId) {
tenantRepository.findById(tenantId)
.orElseThrow(() -> new IllegalArgumentException("租户不存在"));
return appRepository.findByTenantId(tenantId);
}
2026-04-21 22:07:29 +08:00
public void toggleStatus(String tenantId) {
TenantEntity tenant = tenantRepository.findById(tenantId)
.orElseThrow(() -> new IllegalArgumentException("租户不存在"));
if (tenant.getStatus() == TenantEntity.Status.ACTIVE) {
tenant.setStatus(TenantEntity.Status.DISABLED);
} else {
tenant.setStatus(TenantEntity.Status.ACTIVE);
}
tenantRepository.save(tenant);
}
public Map<String, Object> statistics() {
long totalTenants = tenantRepository.count();
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
LocalDateTime todayEnd = todayStart.plusDays(1);
long todayNew = tenantRepository.countByCreatedAtBetween(todayStart, todayEnd);
long activeApps = appRepository.count();
return Map.of(
"totalTenants", totalTenants,
"todayNew", todayNew,
"activeApps", activeApps,
"onlineUsers", 0
);
}
public Page<ServiceActivationRequestEntity> listServiceRequests(String statusStr, int page, int size) {
var pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
if (statusStr != null && !statusStr.isEmpty()) {
ServiceActivationRequestEntity.Status status =
ServiceActivationRequestEntity.Status.valueOf(statusStr.toUpperCase());
return requestRepository.findByStatusOrderByCreatedAtDesc(status, pageable);
}
return requestRepository.findAllByOrderByCreatedAtDesc(pageable);
}
public Page<AppEntity> listApps(String keyword, int page, int size) {
var pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
if (keyword == null || keyword.isBlank()) {
return appRepository.findAll(pageable);
}
return appRepository.findByNameContainingIgnoreCaseOrAppKeyContainingIgnoreCase(keyword, keyword, pageable);
}
public Map<String, Object> getAppDetail(String appId) {
AppEntity app = appRepository.findById(appId)
.orElseThrow(() -> new IllegalArgumentException("应用不存在"));
List<FeatureServiceEntity> services = featureServiceRepository.findByAppId(appId);
long enabledCount = services.stream().filter(FeatureServiceEntity::isEnabled).count();
Map<String, Object> result = new LinkedHashMap<>();
result.put("app", app);
result.put("tenant", tenantRepository.findById(app.getTenantId()).orElse(null));
result.put("services", services);
result.put("serviceCount", services.size());
result.put("enabledServiceCount", enabledCount);
return result;
}
public List<FeatureServiceEntity> listAppServices(String appId) {
appRepository.findById(appId)
.orElseThrow(() -> new IllegalArgumentException("应用不存在"));
return featureServiceRepository.findByAppId(appId);
}
public Page<OperationLogEntity> listOperationLogs(int page, int size) {
var pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
return operationLogRepository.findAllByOrderByCreatedAtDesc(pageable);
}
2026-04-21 22:07:29 +08:00
public void initDefaultAdmin(String username, String rawPassword) {
if (opsAdminRepository.findByUsername(username).isPresent()) return;
OpsAdminEntity admin = new OpsAdminEntity();
admin.setId(UUID.randomUUID().toString());
admin.setUsername(username);
admin.setPassword(passwordEncoder.encode(rawPassword));
admin.setCreatedAt(LocalDateTime.now());
opsAdminRepository.save(admin);
}
}