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
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()
|
|
));
|
|
}
|
|
}
|
|
}
|