XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/controller/AppController.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

122 行
5.7 KiB
Java

package com.xuqm.tenant.controller;
import com.xuqm.common.model.ApiResponse;
import com.xuqm.tenant.dto.CreateAppRequest;
import com.xuqm.tenant.entity.AppEntity;
import com.xuqm.tenant.entity.TenantEntity;
import com.xuqm.tenant.repository.TenantRepository;
import com.xuqm.tenant.service.AppService;
import com.xuqm.tenant.service.EmailService;
import com.xuqm.tenant.service.OperationLogService;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/apps")
public class AppController {
private final AppService appService;
private final EmailService emailService;
private final OperationLogService operationLogService;
private final TenantRepository tenantRepository;
public AppController(AppService appService, EmailService emailService,
OperationLogService operationLogService,
TenantRepository tenantRepository) {
this.appService = appService;
this.emailService = emailService;
this.operationLogService = operationLogService;
this.tenantRepository = tenantRepository;
}
@GetMapping
public ResponseEntity<ApiResponse<List<AppEntity>>> list(@AuthenticationPrincipal String tenantId) {
return ResponseEntity.ok(ApiResponse.success(appService.listByTenant(tenantId)));
}
@GetMapping("/{id}")
public ResponseEntity<ApiResponse<AppEntity>> get(@PathVariable String id,
@AuthenticationPrincipal String tenantId) {
return ResponseEntity.ok(ApiResponse.success(appService.getById(id, tenantId)));
}
@PostMapping
public ResponseEntity<ApiResponse<AppEntity>> create(@Valid @RequestBody CreateAppRequest req,
@AuthenticationPrincipal String tenantId) {
return ResponseEntity.ok(ApiResponse.success(appService.create(tenantId, req)));
}
@PutMapping("/{id}")
public ResponseEntity<ApiResponse<AppEntity>> update(@PathVariable String id,
@Valid @RequestBody CreateAppRequest req,
@AuthenticationPrincipal String tenantId) {
return ResponseEntity.ok(ApiResponse.success(appService.update(id, tenantId, req)));
}
@DeleteMapping("/{id}")
public ResponseEntity<ApiResponse<Void>> delete(@PathVariable String id,
@AuthenticationPrincipal String tenantId) {
appService.delete(id, tenantId);
return ResponseEntity.ok(ApiResponse.ok());
}
/** Step 1: send email verification code for secret reveal or reset. */
@PostMapping("/{id}/request-secret-verify")
public ResponseEntity<ApiResponse<Void>> requestSecretVerify(
@PathVariable String id,
@RequestParam String purpose,
@AuthenticationPrincipal String tenantId) {
appService.getById(id, tenantId);
TenantEntity tenant = tenantRepository.findById(tenantId)
.orElseThrow(() -> new RuntimeException("Tenant not found"));
emailService.sendVerificationCode(tenant.getEmail(), purpose);
operationLogService.record(tenantId, "APP", "APP_SECRET", id, "REQUEST_SECRET_VERIFY", Map.of(
"purpose", purpose
));
return ResponseEntity.ok(ApiResponse.ok());
}
/** Step 2a: verify code and return the full appSecret. */
@PostMapping("/{id}/reveal-secret")
public ResponseEntity<ApiResponse<Map<String, String>>> revealSecret(
@PathVariable String id,
@RequestBody Map<String, String> body,
@AuthenticationPrincipal String tenantId) {
AppEntity app = appService.getById(id, tenantId);
TenantEntity tenant = tenantRepository.findById(tenantId)
.orElseThrow(() -> new RuntimeException("Tenant not found"));
emailService.verify(tenant.getEmail(), body.get("code"), "REVEAL_SECRET");
operationLogService.record(tenantId, "APP", "APP_SECRET", id, "REVEAL_APP_SECRET", Map.of(
"appKey", app.getAppKey()
));
return ResponseEntity.ok(ApiResponse.success(Map.of("appSecret", app.getAppSecret())));
}
/** Step 2b: verify code and regenerate appSecret (old one invalidated immediately). */
@PostMapping("/{id}/reset-secret")
public ResponseEntity<ApiResponse<Map<String, String>>> resetSecret(
@PathVariable String id,
@RequestBody Map<String, String> body,
@AuthenticationPrincipal String tenantId) {
AppEntity app = appService.getById(id, tenantId);
TenantEntity tenant = tenantRepository.findById(tenantId)
.orElseThrow(() -> new RuntimeException("Tenant not found"));
emailService.verify(tenant.getEmail(), body.get("code"), "RESET_SECRET");
String newSecret = appService.resetSecret(id, tenantId);
return ResponseEntity.ok(ApiResponse.success(Map.of("appSecret", newSecret)));
}
}