package com.wok.supportbot.controller; import com.wok.supportbot.entity.SysUser; import com.wok.supportbot.entity.WebhookConfig; import com.wok.supportbot.service.SysUserService; import com.wok.supportbot.service.WebhookService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; import java.util.*; /** * Webhook 管理接口 * 提供 Webhook 的创建、更新、删除、分页查询、测试推送等操作。 */ @Slf4j @RestController @RequestMapping("/webhook") public class WebhookController { @Autowired private WebhookService webhookService; @Autowired private SysUserService sysUserService; /** * 分页查询 Webhook 列表 */ @GetMapping("/list") @PreAuthorize("hasRole('admin')") public ResponseEntity> list( @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int size, @RequestParam(required = false) String sortField, @RequestParam(required = false) String sortOrder) { try { Map result = webhookService.listWebhooks(page, size, sortField, sortOrder); Map data = new HashMap<>(); data.put("success", true); data.put("data", result.get("records")); data.put("total", result.get("total")); data.put("page", result.get("page")); data.put("size", result.get("size")); data.put("pages", result.get("pages")); return ResponseEntity.ok(data); } catch (Exception e) { log.error("查询 Webhook 列表失败", e); return ResponseEntity.status(500).body(Map.of( "success", false, "message", "查询失败:" + e.getMessage() )); } } /** * 创建 Webhook * * @param body 请求体,包含 name, url, events(事件列表) */ @SuppressWarnings("unchecked") @PostMapping @PreAuthorize("hasRole('admin')") public ResponseEntity> create(@RequestBody Map body) { try { String name = (String) body.get("name"); String url = (String) body.get("url"); if (name == null || name.isBlank()) { return ResponseEntity.badRequest().body(Map.of( "success", false, "message", "名称不能为空" )); } if (url == null || url.isBlank()) { return ResponseEntity.badRequest().body(Map.of( "success", false, "message", "URL 不能为空" )); } List events = body.get("events") instanceof List ? ((List) body.get("events")) : new ArrayList<>(); // 从 SecurityContext 获取当前登录用户 ID Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth == null || !auth.isAuthenticated() || "anonymousUser".equals(auth.getPrincipal())) { return ResponseEntity.status(401).body(Map.of( "success", false, "message", "未登录,无法创建 Webhook" )); } SysUser currentUser = sysUserService.getUserByUsername(auth.getName()); Long userId = (currentUser != null) ? currentUser.getId() : null; WebhookConfig config = webhookService.createWebhook(userId, name, url, events); return ResponseEntity.ok(Map.of( "success", true, "message", "创建成功", "data", config )); } catch (Exception e) { log.error("创建 Webhook 失败", e); return ResponseEntity.status(500).body(Map.of( "success", false, "message", "创建失败:" + e.getMessage() )); } } /** * 更新 Webhook * * @param id Webhook ID * @param body 请求体,包含 name, url, events, enabled(均可选) */ @SuppressWarnings("unchecked") @PutMapping("/{id}") @PreAuthorize("hasRole('admin')") public ResponseEntity> update(@PathVariable Long id, @RequestBody Map body) { try { String name = body.containsKey("name") ? (String) body.get("name") : null; String url = body.containsKey("url") ? (String) body.get("url") : null; List events = body.get("events") instanceof List ? ((List) body.get("events")) : null; Boolean enabled = body.containsKey("enabled") ? (Boolean) body.get("enabled") : null; WebhookConfig config = webhookService.updateWebhook(id, name, url, events, enabled); return ResponseEntity.ok(Map.of( "success", true, "message", "更新成功", "data", config )); } catch (IllegalArgumentException e) { return ResponseEntity.badRequest().body(Map.of( "success", false, "message", e.getMessage() )); } catch (Exception e) { log.error("更新 Webhook 失败", e); return ResponseEntity.status(500).body(Map.of( "success", false, "message", "更新失败:" + e.getMessage() )); } } /** * 删除 Webhook */ @DeleteMapping("/{id}") @PreAuthorize("hasRole('admin')") public ResponseEntity> delete(@PathVariable Long id) { try { webhookService.deleteWebhook(id); return ResponseEntity.ok(Map.of( "success", true, "message", "删除成功" )); } catch (IllegalArgumentException e) { return ResponseEntity.badRequest().body(Map.of( "success", false, "message", e.getMessage() )); } catch (Exception e) { log.error("删除 Webhook 失败", e); return ResponseEntity.status(500).body(Map.of( "success", false, "message", "删除失败:" + e.getMessage() )); } } /** * 测试 Webhook 推送 * 向指定 Webhook 发送一条测试事件,验证连通性。 * * @param id Webhook ID */ @PostMapping("/{id}/test") @PreAuthorize("hasRole('admin')") public ResponseEntity> test(@PathVariable Long id) { try { Map testPayload = Map.of( "message", "这是一条 Webhook 测试推送", "webhookId", id.toString() ); // 直接触发测试事件(使用同步方式以便立即返回结果) // triggerEvent 是异步的,这里手动构建测试请求 webhookService.triggerEvent("test.ping", testPayload); return ResponseEntity.ok(Map.of( "success", true, "message", "测试推送已发送,请检查目标 URL 是否收到请求" )); } catch (Exception e) { log.error("Webhook 测试推送失败", e); return ResponseEntity.status(500).body(Map.of( "success", false, "message", "测试推送失败:" + e.getMessage() )); } } }