WebhookController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. namespace App\Module\OpenAPI\Controllers;
  3. use App\Module\OpenAPI\Models\OpenApiWebhook;
  4. use App\Module\OpenAPI\Services\WebhookService;
  5. use Illuminate\Http\Request;
  6. use Illuminate\Http\JsonResponse;
  7. use Spatie\RouteAttributes\Attributes\Route;
  8. use Spatie\RouteAttributes\Attributes\Prefix;
  9. use Spatie\RouteAttributes\Attributes\Middleware;
  10. /**
  11. * OpenAPI Webhook控制器
  12. *
  13. * 提供Webhook配置和管理的API接口
  14. */
  15. #[Prefix('openapi/webhook')]
  16. #[Middleware(['api', 'openapi.auth'])]
  17. class WebhookController
  18. {
  19. protected WebhookService $webhookService;
  20. public function __construct(WebhookService $webhookService)
  21. {
  22. $this->webhookService = $webhookService;
  23. }
  24. /**
  25. * 获取Webhook列表
  26. *
  27. * @param Request $request
  28. * @return JsonResponse
  29. */
  30. #[Route('GET', '/', name: 'openapi.webhook.index')]
  31. #[Middleware('openapi.scope:WEBHOOK_READ')]
  32. public function index(Request $request): JsonResponse
  33. {
  34. try {
  35. $app = $request->attributes->get('openapi_app');
  36. if (!$app) {
  37. return response()->json([
  38. 'success' => false,
  39. 'message' => '应用信息不存在',
  40. ], 404);
  41. }
  42. $webhooks = OpenApiWebhook::where('app_id', $app->app_id)
  43. ->orderBy('created_at', 'desc')
  44. ->get()
  45. ->map(function ($webhook) {
  46. return [
  47. 'id' => $webhook->id,
  48. 'name' => $webhook->name,
  49. 'url' => $webhook->url,
  50. 'events' => $webhook->events,
  51. 'status' => $webhook->status,
  52. 'status_label' => $webhook->status_label,
  53. 'success_rate' => $webhook->success_rate,
  54. 'total_deliveries' => $webhook->total_deliveries,
  55. 'successful_deliveries' => $webhook->successful_deliveries,
  56. 'failed_deliveries' => $webhook->failed_deliveries,
  57. 'last_success_at' => $webhook->last_success_at,
  58. 'last_failure_at' => $webhook->last_failure_at,
  59. 'created_at' => $webhook->created_at,
  60. ];
  61. });
  62. return response()->json([
  63. 'success' => true,
  64. 'data' => $webhooks,
  65. ]);
  66. } catch (\Exception $e) {
  67. return response()->json([
  68. 'success' => false,
  69. 'message' => '获取Webhook列表失败',
  70. 'error' => $e->getMessage(),
  71. ], 500);
  72. }
  73. }
  74. /**
  75. * 创建Webhook
  76. *
  77. * @param Request $request
  78. * @return JsonResponse
  79. */
  80. #[Route('POST', '/', name: 'openapi.webhook.store')]
  81. #[Middleware('openapi.scope:WEBHOOK_WRITE')]
  82. public function store(Request $request): JsonResponse
  83. {
  84. try {
  85. $app = $request->attributes->get('openapi_app');
  86. if (!$app) {
  87. return response()->json([
  88. 'success' => false,
  89. 'message' => '应用信息不存在',
  90. ], 404);
  91. }
  92. // 使用标准验证系统
  93. $validation = new \App\Module\OpenAPI\Validations\WebhookCreateValidation($request->all());
  94. $validation->validate();
  95. if ($validation->isFail()) {
  96. return response()->json([
  97. 'success' => false,
  98. 'message' => '数据验证失败',
  99. 'errors' => $validation->getErrors(),
  100. ], 422);
  101. }
  102. $data = $validation->getSafeData();
  103. // 创建Webhook
  104. $webhook = $this->webhookService->createWebhook($app, $data);
  105. return response()->json([
  106. 'success' => true,
  107. 'message' => 'Webhook创建成功',
  108. 'data' => [
  109. 'id' => $webhook->id,
  110. 'name' => $webhook->name,
  111. 'url' => $webhook->url,
  112. 'events' => $webhook->events,
  113. 'secret' => $webhook->secret,
  114. 'status' => $webhook->status,
  115. 'timeout' => $webhook->timeout,
  116. 'retry_count' => $webhook->retry_count,
  117. 'created_at' => $webhook->created_at,
  118. ],
  119. ]);
  120. } catch (\Exception $e) {
  121. return response()->json([
  122. 'success' => false,
  123. 'message' => '创建Webhook失败',
  124. 'error' => $e->getMessage(),
  125. ], 500);
  126. }
  127. }
  128. /**
  129. * 获取Webhook详情
  130. *
  131. * @param Request $request
  132. * @param int $id
  133. * @return JsonResponse
  134. */
  135. #[Route('GET', '/{id}', name: 'openapi.webhook.show')]
  136. #[Middleware('openapi.scope:WEBHOOK_READ')]
  137. public function show(Request $request, int $id): JsonResponse
  138. {
  139. try {
  140. $app = $request->attributes->get('openapi_app');
  141. if (!$app) {
  142. return response()->json([
  143. 'success' => false,
  144. 'message' => '应用信息不存在',
  145. ], 404);
  146. }
  147. $webhook = OpenApiWebhook::where('app_id', $app->app_id)
  148. ->where('id', $id)
  149. ->first();
  150. if (!$webhook) {
  151. return response()->json([
  152. 'success' => false,
  153. 'message' => 'Webhook不存在',
  154. ], 404);
  155. }
  156. return response()->json([
  157. 'success' => true,
  158. 'data' => [
  159. 'id' => $webhook->id,
  160. 'name' => $webhook->name,
  161. 'url' => $webhook->url,
  162. 'events' => $webhook->events,
  163. 'secret' => $webhook->masked_secret,
  164. 'status' => $webhook->status,
  165. 'status_label' => $webhook->status_label,
  166. 'timeout' => $webhook->timeout,
  167. 'retry_count' => $webhook->retry_count,
  168. 'current_retry_count' => $webhook->current_retry_count,
  169. 'total_deliveries' => $webhook->total_deliveries,
  170. 'successful_deliveries' => $webhook->successful_deliveries,
  171. 'failed_deliveries' => $webhook->failed_deliveries,
  172. 'success_rate' => $webhook->success_rate,
  173. 'last_success_at' => $webhook->last_success_at,
  174. 'last_failure_at' => $webhook->last_failure_at,
  175. 'created_at' => $webhook->created_at,
  176. 'updated_at' => $webhook->updated_at,
  177. ],
  178. ]);
  179. } catch (\Exception $e) {
  180. return response()->json([
  181. 'success' => false,
  182. 'message' => '获取Webhook详情失败',
  183. 'error' => $e->getMessage(),
  184. ], 500);
  185. }
  186. }
  187. /**
  188. * 更新Webhook
  189. *
  190. * @param Request $request
  191. * @param int $id
  192. * @return JsonResponse
  193. */
  194. #[Route('PUT', '/{id}', name: 'openapi.webhook.update')]
  195. #[Middleware('openapi.scope:WEBHOOK_WRITE')]
  196. public function update(Request $request, int $id): JsonResponse
  197. {
  198. try {
  199. $app = $request->attributes->get('openapi_app');
  200. if (!$app) {
  201. return response()->json([
  202. 'success' => false,
  203. 'message' => '应用信息不存在',
  204. ], 404);
  205. }
  206. $webhook = OpenApiWebhook::where('app_id', $app->app_id)
  207. ->where('id', $id)
  208. ->first();
  209. if (!$webhook) {
  210. return response()->json([
  211. 'success' => false,
  212. 'message' => 'Webhook不存在',
  213. ], 404);
  214. }
  215. // 使用标准验证系统
  216. $requestData = $request->only(['name', 'url', 'events', 'status', 'timeout', 'retry_count']);
  217. $validation = new \App\Module\OpenAPI\Validations\WebhookUpdateValidation($requestData);
  218. $validation->validate();
  219. if ($validation->isFail()) {
  220. return response()->json([
  221. 'success' => false,
  222. 'message' => '数据验证失败',
  223. 'errors' => $validation->getErrors(),
  224. ], 422);
  225. }
  226. $data = $validation->getSafeData();
  227. // 更新Webhook
  228. $webhook->update(array_filter($data));
  229. return response()->json([
  230. 'success' => true,
  231. 'message' => 'Webhook更新成功',
  232. 'data' => [
  233. 'id' => $webhook->id,
  234. 'name' => $webhook->name,
  235. 'url' => $webhook->url,
  236. 'events' => $webhook->events,
  237. 'status' => $webhook->status,
  238. 'timeout' => $webhook->timeout,
  239. 'retry_count' => $webhook->retry_count,
  240. 'updated_at' => $webhook->updated_at,
  241. ],
  242. ]);
  243. } catch (\Exception $e) {
  244. return response()->json([
  245. 'success' => false,
  246. 'message' => '更新Webhook失败',
  247. 'error' => $e->getMessage(),
  248. ], 500);
  249. }
  250. }
  251. /**
  252. * 删除Webhook
  253. *
  254. * @param Request $request
  255. * @param int $id
  256. * @return JsonResponse
  257. */
  258. #[Route('DELETE', '/{id}', name: 'openapi.webhook.destroy')]
  259. #[Middleware('openapi.scope:WEBHOOK_WRITE')]
  260. public function destroy(Request $request, int $id): JsonResponse
  261. {
  262. try {
  263. $app = $request->attributes->get('openapi_app');
  264. if (!$app) {
  265. return response()->json([
  266. 'success' => false,
  267. 'message' => '应用信息不存在',
  268. ], 404);
  269. }
  270. $webhook = OpenApiWebhook::where('app_id', $app->app_id)
  271. ->where('id', $id)
  272. ->first();
  273. if (!$webhook) {
  274. return response()->json([
  275. 'success' => false,
  276. 'message' => 'Webhook不存在',
  277. ], 404);
  278. }
  279. $webhook->delete();
  280. return response()->json([
  281. 'success' => true,
  282. 'message' => 'Webhook删除成功',
  283. ]);
  284. } catch (\Exception $e) {
  285. return response()->json([
  286. 'success' => false,
  287. 'message' => '删除Webhook失败',
  288. 'error' => $e->getMessage(),
  289. ], 500);
  290. }
  291. }
  292. /**
  293. * 测试Webhook
  294. *
  295. * @param Request $request
  296. * @param int $id
  297. * @return JsonResponse
  298. */
  299. #[Route('POST', '/{id}/test', name: 'openapi.webhook.test')]
  300. #[Middleware('openapi.scope:WEBHOOK_WRITE')]
  301. public function test(Request $request, int $id): JsonResponse
  302. {
  303. try {
  304. $app = $request->attributes->get('openapi_app');
  305. if (!$app) {
  306. return response()->json([
  307. 'success' => false,
  308. 'message' => '应用信息不存在',
  309. ], 404);
  310. }
  311. $webhook = OpenApiWebhook::where('app_id', $app->app_id)
  312. ->where('id', $id)
  313. ->first();
  314. if (!$webhook) {
  315. return response()->json([
  316. 'success' => false,
  317. 'message' => 'Webhook不存在',
  318. ], 404);
  319. }
  320. // 测试Webhook
  321. $result = $this->webhookService->testWebhook($webhook);
  322. return response()->json([
  323. 'success' => true,
  324. 'message' => 'Webhook测试完成',
  325. 'data' => $result,
  326. ]);
  327. } catch (\Exception $e) {
  328. return response()->json([
  329. 'success' => false,
  330. 'message' => 'Webhook测试失败',
  331. 'error' => $e->getMessage(),
  332. ], 500);
  333. }
  334. }
  335. /**
  336. * 重新生成Webhook密钥
  337. *
  338. * @param Request $request
  339. * @param int $id
  340. * @return JsonResponse
  341. */
  342. #[Route('POST', '/{id}/regenerate-secret', name: 'openapi.webhook.regenerate_secret')]
  343. #[Middleware('openapi.scope:WEBHOOK_WRITE')]
  344. public function regenerateSecret(Request $request, int $id): JsonResponse
  345. {
  346. try {
  347. $app = $request->attributes->get('openapi_app');
  348. if (!$app) {
  349. return response()->json([
  350. 'success' => false,
  351. 'message' => '应用信息不存在',
  352. ], 404);
  353. }
  354. $webhook = OpenApiWebhook::where('app_id', $app->app_id)
  355. ->where('id', $id)
  356. ->first();
  357. if (!$webhook) {
  358. return response()->json([
  359. 'success' => false,
  360. 'message' => 'Webhook不存在',
  361. ], 404);
  362. }
  363. // 重新生成密钥
  364. $newSecret = $webhook->regenerateSecret();
  365. return response()->json([
  366. 'success' => true,
  367. 'message' => 'Webhook密钥重新生成成功',
  368. 'data' => [
  369. 'webhook_id' => $webhook->id,
  370. 'secret' => $newSecret,
  371. 'regenerated_at' => now(),
  372. ],
  373. ]);
  374. } catch (\Exception $e) {
  375. return response()->json([
  376. 'success' => false,
  377. 'message' => '重新生成密钥失败',
  378. 'error' => $e->getMessage(),
  379. ], 500);
  380. }
  381. }
  382. }