本地 RAG 知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

210 lines
7.9 KiB

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<Map<String, Object>> list(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) String sortField,
@RequestParam(required = false) String sortOrder) {
try {
Map<String, Object> result = webhookService.listWebhooks(page, size, sortField, sortOrder);
Map<String, Object> 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<Map<String, Object>> create(@RequestBody Map<String, Object> 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<String> events = body.get("events") instanceof List<?>
? ((List<String>) 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<Map<String, Object>> update(@PathVariable Long id,
@RequestBody Map<String, Object> body) {
try {
String name = body.containsKey("name") ? (String) body.get("name") : null;
String url = body.containsKey("url") ? (String) body.get("url") : null;
List<String> events = body.get("events") instanceof List<?>
? ((List<String>) 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<Map<String, Object>> 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<Map<String, Object>> test(@PathVariable Long id) {
try {
Map<String, Object> 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()
));
}
}
}