XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/service/OpsService.java
XuqmGroup d2dea0c332 feat(android-sdk): 添加完整的IM客户端SDK实现
- 实现了Android SDK的完整IM功能接口,包括消息、群组、好友、会话等核心功能
- 添加了消息收发、历史记录、撤回编辑等完整的消息操作能力
- 实现了群组管理功能,包括创建、成员管理、权限设置等操作
- 添加了好友关系链管理,支持添加、删除、分组等操作
- 实现了会话管理功能,包括置顶、免打扰、已读状态等
- 添加了黑名单、资料管理、搜索等辅助功能
- 补齐了批量操作接口,提升客户端操作效率
- 实现了WebSocket连接管理和事件监听机制
- 添加了离线消息同步和状态管理功能
2026-05-02 22:57:55 +08:00

201 行
9.2 KiB
Java

package com.xuqm.tenant.service;
import com.xuqm.common.security.JwtUtil;
import com.xuqm.tenant.entity.AppEntity;
import com.xuqm.tenant.entity.FeatureServiceEntity;
import com.xuqm.tenant.entity.OpsAdminEntity;
import com.xuqm.tenant.entity.OperationLogEntity;
import com.xuqm.tenant.entity.ServiceActivationRequestEntity;
import com.xuqm.tenant.entity.TenantEntity;
import com.xuqm.tenant.repository.AppRepository;
import com.xuqm.tenant.repository.FeatureServiceRepository;
import com.xuqm.tenant.repository.OpsAdminRepository;
import com.xuqm.tenant.repository.OperationLogRepository;
import com.xuqm.tenant.repository.ServiceActivationRequestRepository;
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.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Service
public class OpsService {
private final TenantRepository tenantRepository;
private final AppRepository appRepository;
private final FeatureServiceRepository featureServiceRepository;
private final OpsAdminRepository opsAdminRepository;
private final ServiceActivationRequestRepository requestRepository;
private final OperationLogRepository operationLogRepository;
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) {
this.tenantRepository = tenantRepository;
this.appRepository = appRepository;
this.featureServiceRepository = featureServiceRepository;
this.opsAdminRepository = opsAdminRepository;
this.requestRepository = requestRepository;
this.operationLogRepository = operationLogRepository;
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);
}
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();
List<Map<String, Object>> dailyTrend = new ArrayList<>();
for (int i = 6; i >= 0; i--) {
LocalDate d = LocalDate.now().minusDays(i);
long count = tenantRepository.countByCreatedAtBetween(d.atStartOfDay(), d.plusDays(1).atStartOfDay());
dailyTrend.add(Map.of("date", d.toString(), "count", count));
}
List<FeatureServiceEntity> services = featureServiceRepository.findAll();
Map<String, Long> serviceDistribution = services.stream()
.filter(FeatureServiceEntity::isEnabled)
.collect(java.util.stream.Collectors.groupingBy(
s -> s.getServiceType().name(), java.util.stream.Collectors.counting()));
return Map.of(
"totalTenants", totalTenants,
"todayNew", todayNew,
"activeApps", activeApps,
"onlineUsers", 0,
"dailyTrend", dailyTrend,
"serviceDistribution", serviceDistribution
);
}
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);
}
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);
}
}