package com.xuqm.tenant.controller; import com.xuqm.common.model.ApiResponse; import com.xuqm.tenant.entity.AppEntity; import com.xuqm.tenant.entity.FeatureServiceEntity; import com.xuqm.tenant.entity.OperationLogEntity; import com.xuqm.tenant.entity.ServiceActivationRequestEntity; import com.xuqm.tenant.dto.ServiceRequestView; import com.xuqm.tenant.entity.TenantEntity; import com.xuqm.tenant.service.FeatureServiceManager; import com.xuqm.tenant.entity.RiskConfigEntity; import com.xuqm.tenant.entity.SensitiveWordEntity; import com.xuqm.tenant.service.OpsService; import com.xuqm.tenant.service.OpsPushDiagnosticsClient; import com.xuqm.tenant.service.RiskControlService; import org.springframework.data.domain.Page; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; 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.Map; @RestController @RequestMapping public class OpsController { private final OpsService opsService; private final FeatureServiceManager featureServiceManager; private final RiskControlService riskControlService; private final OpsPushDiagnosticsClient pushDiagnosticsClient; public OpsController(OpsService opsService, FeatureServiceManager featureServiceManager, RiskControlService riskControlService, OpsPushDiagnosticsClient pushDiagnosticsClient) { this.opsService = opsService; this.featureServiceManager = featureServiceManager; this.riskControlService = riskControlService; this.pushDiagnosticsClient = pushDiagnosticsClient; } @PostMapping("/api/auth/ops/login") public ResponseEntity>> opsLogin(@RequestBody Map body) { String token = opsService.login(body.get("username"), body.get("password")); return ResponseEntity.ok(ApiResponse.success(Map.of("token", token))); } @GetMapping("/api/ops/tenants") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listTenants( @RequestParam(defaultValue = "") String keyword, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { Page result = opsService.listTenants(keyword, page, size); return ResponseEntity.ok(ApiResponse.success(Map.of( "content", result.getContent(), "total", result.getTotalElements(), "totalPages", result.getTotalPages() ))); } @PostMapping("/api/ops/tenants/{id}/toggle-status") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> toggleStatus(@PathVariable String id) { opsService.toggleStatus(id); return ResponseEntity.ok(ApiResponse.ok()); } @GetMapping("/api/ops/tenants/{id}") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> getTenantDetail(@PathVariable String id) { return ResponseEntity.ok(ApiResponse.success(opsService.getTenantDetail(id))); } @GetMapping("/api/ops/tenants/{id}/apps") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listTenantApps(@PathVariable String id) { return ResponseEntity.ok(ApiResponse.success(opsService.listTenantApps(id))); } @GetMapping("/api/ops/statistics") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> statistics() { return ResponseEntity.ok(ApiResponse.success(opsService.statistics())); } @GetMapping("/api/ops/service-requests") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listServiceRequests( @RequestParam(required = false) String status, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { Page result = opsService.listServiceRequests(status, page, size); return ResponseEntity.ok(ApiResponse.success(Map.of( "content", result.getContent(), "total", result.getTotalElements(), "totalPages", result.getTotalPages() ))); } @PostMapping("/api/ops/service-requests/{requestId}/approve") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> approveRequest( @PathVariable String requestId, @RequestBody(required = false) Map body) { String reviewNote = body != null ? body.getOrDefault("reviewNote", "") : ""; return ResponseEntity.ok(ApiResponse.success( featureServiceManager.approveRequest(requestId, reviewNote))); } @PostMapping("/api/ops/service-requests/{requestId}/reject") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> rejectRequest( @PathVariable String requestId, @RequestBody(required = false) Map body) { String reviewNote = body != null ? body.getOrDefault("reviewNote", "") : ""; return ResponseEntity.ok(ApiResponse.success( featureServiceManager.rejectRequest(requestId, reviewNote))); } @GetMapping("/api/ops/apps") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listApps( @RequestParam(defaultValue = "") String keyword, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { Page result = opsService.listApps(keyword, page, size); return ResponseEntity.ok(ApiResponse.success(Map.of( "content", result.getContent(), "total", result.getTotalElements(), "totalPages", result.getTotalPages() ))); } @GetMapping("/api/ops/apps/{appKey}") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> getAppDetail(@PathVariable String appKey) { return ResponseEntity.ok(ApiResponse.success(opsService.getAppDetail(appKey))); } @GetMapping("/api/ops/apps/{appKey}/services") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listAppServices(@PathVariable String appKey) { return ResponseEntity.ok(ApiResponse.success(opsService.listAppServices(appKey))); } @GetMapping("/api/ops/operation-logs") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listOperationLogs( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { Page result = opsService.listOperationLogs(page, size); return ResponseEntity.ok(ApiResponse.success(Map.of( "content", result.getContent(), "total", result.getTotalElements(), "totalPages", result.getTotalPages() ))); } @GetMapping("/api/ops/push/search") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> searchPushByToken( @RequestParam String token, @RequestParam(required = false) String appKey) { return ResponseEntity.ok(ApiResponse.success(pushDiagnosticsClient.searchByToken(token, appKey))); } @GetMapping("/api/ops/push/device-logs") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> pushDeviceLogs( @RequestParam String appKey, @RequestParam String userId, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { return ResponseEntity.ok(ApiResponse.success(pushDiagnosticsClient.deviceLogs(appKey, userId, page, size))); } @PostMapping("/api/ops/push/test-offline") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> sendPushTestOffline(@RequestBody Map body) { return ResponseEntity.ok(ApiResponse.success(pushDiagnosticsClient.sendTestOffline( body.get("appKey"), body.get("userId"), body.getOrDefault("title", "XuqmGroup Push 测试"), body.getOrDefault("body", "这是一条离线推送测试消息"), body.getOrDefault("payload", "{}")))); } /* ---------- 风控配置 ---------- */ @GetMapping("/api/ops/risk/rules") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> getRiskConfig() { return ResponseEntity.ok(ApiResponse.success(riskControlService.getConfig())); } @PostMapping("/api/ops/risk/rules") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> saveRiskConfig(@RequestBody RiskConfigEntity req) { return ResponseEntity.ok(ApiResponse.success(riskControlService.saveConfig(req))); } /* ---------- 敏感词 ---------- */ @GetMapping("/api/ops/risk/sensitive-words") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity>> listSensitiveWords( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "20") int size) { Page result = riskControlService.listWords(page, size); return ResponseEntity.ok(ApiResponse.success(Map.of( "content", result.getContent(), "total", result.getTotalElements(), "totalPages", result.getTotalPages() ))); } @PostMapping("/api/ops/risk/sensitive-words") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> createSensitiveWord(@RequestBody SensitiveWordEntity req) { return ResponseEntity.ok(ApiResponse.success(riskControlService.createWord(req))); } @PutMapping("/api/ops/risk/sensitive-words/{id}") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> updateSensitiveWord( @PathVariable String id, @RequestBody SensitiveWordEntity req) { return ResponseEntity.ok(ApiResponse.success(riskControlService.updateWord(id, req))); } @PatchMapping("/api/ops/risk/sensitive-words/{id}/toggle") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> toggleSensitiveWord( @PathVariable String id, @RequestParam boolean enabled) { riskControlService.toggleWord(id, enabled); return ResponseEntity.ok(ApiResponse.ok()); } @DeleteMapping("/api/ops/risk/sensitive-words/{id}") @PreAuthorize("hasAuthority('ROLE_OPS')") public ResponseEntity> deleteSensitiveWord(@PathVariable String id) { riskControlService.deleteWord(id); return ResponseEntity.ok(ApiResponse.ok()); } }