2026-04-21 22:07:29 +08:00
|
|
|
package com.xuqm.tenant.service;
|
|
|
|
|
|
|
|
|
|
import com.xuqm.common.exception.BusinessException;
|
|
|
|
|
import com.xuqm.tenant.dto.CreateAppRequest;
|
|
|
|
|
import com.xuqm.tenant.entity.AppEntity;
|
|
|
|
|
import com.xuqm.tenant.repository.AppRepository;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
|
import java.security.SecureRandom;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.util.Base64;
|
2026-04-30 09:49:05 +08:00
|
|
|
import java.util.LinkedHashMap;
|
2026-04-21 22:07:29 +08:00
|
|
|
import java.util.List;
|
2026-04-30 09:49:05 +08:00
|
|
|
import java.util.Map;
|
2026-04-21 22:07:29 +08:00
|
|
|
import java.util.UUID;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
|
|
|
public class AppService {
|
|
|
|
|
|
|
|
|
|
private final AppRepository appRepository;
|
2026-04-30 09:49:05 +08:00
|
|
|
private final OperationLogService operationLogService;
|
2026-04-21 22:07:29 +08:00
|
|
|
private static final SecureRandom random = new SecureRandom();
|
|
|
|
|
|
2026-04-30 09:49:05 +08:00
|
|
|
public AppService(AppRepository appRepository, OperationLogService operationLogService) {
|
2026-04-21 22:07:29 +08:00
|
|
|
this.appRepository = appRepository;
|
2026-04-30 09:49:05 +08:00
|
|
|
this.operationLogService = operationLogService;
|
2026-04-21 22:07:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<AppEntity> listByTenant(String tenantId) {
|
|
|
|
|
return appRepository.findByTenantId(tenantId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AppEntity getById(String id, String tenantId) {
|
|
|
|
|
AppEntity app = appRepository.findById(id)
|
|
|
|
|
.orElseThrow(() -> new BusinessException(404, "应用不存在"));
|
|
|
|
|
if (!app.getTenantId().equals(tenantId)) {
|
|
|
|
|
throw new BusinessException(403, "无权访问该应用");
|
|
|
|
|
}
|
|
|
|
|
return app;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AppEntity create(String tenantId, CreateAppRequest req) {
|
|
|
|
|
if (appRepository.existsByPackageNameAndTenantId(req.packageName(), tenantId)) {
|
|
|
|
|
throw new BusinessException("该包名下已存在同名应用");
|
|
|
|
|
}
|
|
|
|
|
AppEntity app = new AppEntity();
|
|
|
|
|
app.setId(UUID.randomUUID().toString());
|
|
|
|
|
app.setTenantId(tenantId);
|
|
|
|
|
app.setPackageName(req.packageName());
|
|
|
|
|
app.setName(req.name());
|
|
|
|
|
app.setDescription(req.description());
|
|
|
|
|
app.setIconUrl(req.iconUrl());
|
|
|
|
|
app.setAppKey(generateAppKey());
|
|
|
|
|
app.setAppSecret(generateSecret());
|
|
|
|
|
app.setCreatedAt(LocalDateTime.now());
|
2026-04-30 09:49:05 +08:00
|
|
|
AppEntity saved = appRepository.save(app);
|
|
|
|
|
operationLogService.record(tenantId, "APP", "APP", saved.getId(), "CREATE_APP", Map.of(
|
|
|
|
|
"name", saved.getName(),
|
|
|
|
|
"packageName", saved.getPackageName(),
|
|
|
|
|
"appKey", saved.getAppKey()
|
|
|
|
|
));
|
|
|
|
|
return saved;
|
2026-04-21 22:07:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AppEntity update(String id, String tenantId, CreateAppRequest req) {
|
|
|
|
|
AppEntity app = getById(id, tenantId);
|
2026-04-30 09:49:05 +08:00
|
|
|
Map<String, Object> before = new LinkedHashMap<>();
|
|
|
|
|
before.put("name", app.getName());
|
|
|
|
|
before.put("packageName", app.getPackageName());
|
|
|
|
|
before.put("description", app.getDescription());
|
|
|
|
|
before.put("iconUrl", app.getIconUrl());
|
2026-04-21 22:07:29 +08:00
|
|
|
app.setName(req.name());
|
|
|
|
|
app.setDescription(req.description());
|
|
|
|
|
app.setIconUrl(req.iconUrl());
|
2026-04-30 09:49:05 +08:00
|
|
|
AppEntity saved = appRepository.save(app);
|
|
|
|
|
Map<String, Object> after = new LinkedHashMap<>();
|
|
|
|
|
after.put("name", saved.getName());
|
|
|
|
|
after.put("packageName", saved.getPackageName());
|
|
|
|
|
after.put("description", saved.getDescription());
|
|
|
|
|
after.put("iconUrl", saved.getIconUrl());
|
|
|
|
|
operationLogService.record(tenantId, "APP", "APP", saved.getId(), "UPDATE_APP", Map.of(
|
|
|
|
|
"before", before,
|
|
|
|
|
"after", after
|
|
|
|
|
));
|
|
|
|
|
return saved;
|
2026-04-21 22:07:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void delete(String id, String tenantId) {
|
|
|
|
|
AppEntity app = getById(id, tenantId);
|
|
|
|
|
appRepository.delete(app);
|
2026-04-30 09:49:05 +08:00
|
|
|
operationLogService.record(tenantId, "APP", "APP", id, "DELETE_APP", Map.of(
|
|
|
|
|
"name", app.getName(),
|
|
|
|
|
"packageName", app.getPackageName(),
|
|
|
|
|
"appKey", app.getAppKey()
|
|
|
|
|
));
|
2026-04-21 22:07:29 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 20:53:48 +08:00
|
|
|
public String resetSecret(String id, String tenantId) {
|
|
|
|
|
AppEntity app = getById(id, tenantId);
|
|
|
|
|
String newSecret = generateSecret();
|
|
|
|
|
app.setAppSecret(newSecret);
|
|
|
|
|
appRepository.save(app);
|
2026-04-30 09:49:05 +08:00
|
|
|
operationLogService.record(tenantId, "APP", "APP_SECRET", id, "RESET_APP_SECRET", Map.of(
|
|
|
|
|
"name", app.getName(),
|
|
|
|
|
"packageName", app.getPackageName(),
|
|
|
|
|
"appKey", app.getAppKey()
|
|
|
|
|
));
|
2026-04-24 20:53:48 +08:00
|
|
|
return newSecret;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-21 22:07:29 +08:00
|
|
|
private String generateAppKey() {
|
|
|
|
|
return "ak_" + UUID.randomUUID().toString().replace("-", "").substring(0, 24);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String generateSecret() {
|
|
|
|
|
byte[] bytes = new byte[32];
|
|
|
|
|
random.nextBytes(bytes);
|
|
|
|
|
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
|
|
|
|
|
}
|
|
|
|
|
}
|