From b666924fb6a00c0816ae553ffbc5b6cd8d5b9868 Mon Sep 17 00:00:00 2001 From: fit2cloud-chenyw Date: Mon, 15 Jun 2026 18:21:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(X-Pack):=20Webhook=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=20body=E5=8F=82=E6=95=B0=20#18445?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form => components/CodeEdit}/CodeEdit.vue | 0 .../CodeEdit}/ace-config.ts | 0 .../CodeEdit}/format-utils.js | 0 core/core-frontend/src/locales/en.ts | 2 ++ core/core-frontend/src/locales/tw.ts | 2 ++ core/core-frontend/src/locales/zh-CN.ts | 2 ++ .../data/datasource/form/ApiBody.vue | 2 +- .../io/dataease/api/webhook/WebhookApi.java | 7 +++- .../api/webhook/vo/WebhookGridVO.java | 5 --- .../io/dataease/api/webhook/vo/WebhookVO.java | 34 +++++++++++++++++++ .../io/dataease/utils/HttpClientUtil.java | 33 ++++++++++++++++++ 11 files changed, 80 insertions(+), 7 deletions(-) rename core/core-frontend/src/{views/visualized/data/datasource/form => components/CodeEdit}/CodeEdit.vue (100%) rename core/core-frontend/src/{views/visualized/data/datasource/form => components/CodeEdit}/ace-config.ts (100%) rename core/core-frontend/src/{views/visualized/data/datasource/form => components/CodeEdit}/format-utils.js (100%) create mode 100644 sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookVO.java diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/CodeEdit.vue b/core/core-frontend/src/components/CodeEdit/CodeEdit.vue similarity index 100% rename from core/core-frontend/src/views/visualized/data/datasource/form/CodeEdit.vue rename to core/core-frontend/src/components/CodeEdit/CodeEdit.vue diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/ace-config.ts b/core/core-frontend/src/components/CodeEdit/ace-config.ts similarity index 100% rename from core/core-frontend/src/views/visualized/data/datasource/form/ace-config.ts rename to core/core-frontend/src/components/CodeEdit/ace-config.ts diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/format-utils.js b/core/core-frontend/src/components/CodeEdit/format-utils.js similarity index 100% rename from core/core-frontend/src/views/visualized/data/datasource/form/format-utils.js rename to core/core-frontend/src/components/CodeEdit/format-utils.js diff --git a/core/core-frontend/src/locales/en.ts b/core/core-frontend/src/locales/en.ts index 55db08725b..2754b47563 100644 --- a/core/core-frontend/src/locales/en.ts +++ b/core/core-frontend/src/locales/en.ts @@ -4895,6 +4895,8 @@ export default { add: 'Add Webhook', search_placeholder: 'Search by name', content_type: 'Content Type', + msg_template: 'Message Template', + msg_template_tips: 'Available placeholders: {t0}, {t1}, {t2}', del_confirm: 'Are you sure you want to delete this Webhook?', batch_del_confirm: 'Are you sure you want to delete {0} Webhooks?' }, diff --git a/core/core-frontend/src/locales/tw.ts b/core/core-frontend/src/locales/tw.ts index f53c5def72..e0adb5050e 100644 --- a/core/core-frontend/src/locales/tw.ts +++ b/core/core-frontend/src/locales/tw.ts @@ -4745,6 +4745,8 @@ export default { add: '添加 Webhook', search_placeholder: '通過名稱搜索', content_type: '內容類型', + msg_template: '消息模板', + msg_template_tips: '可用占位符:{t0}、{t1}、{t2}', del_confirm: '確定刪除該 Webhook嗎?', batch_del_confirm: '確定刪除 {0} 個 Webhook嗎' } diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index 8492244e5a..5bf70d6e99 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -4755,6 +4755,8 @@ export default { add: '添加 Webhook', search_placeholder: '通过名称搜索', content_type: '内容类型', + msg_template: '消息模板', + msg_template_tips: '可用占位符:{t0}、{t1}、{t2}', del_confirm: '确定删除该 Webhook吗?', batch_del_confirm: '确定删除 {0} 个 Webhook吗' }, diff --git a/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue b/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue index 9a058e650d..ec10627fc7 100644 --- a/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue +++ b/core/core-frontend/src/views/visualized/data/datasource/form/ApiBody.vue @@ -3,7 +3,7 @@ import { propTypes } from '@/utils/propTypes' import { onBeforeMount, watch, toRefs, PropType } from 'vue' import { useI18n } from '@/hooks/web/useI18n' import ApiVariable from './ApiVariable.vue' -import CodeEdit from './CodeEdit.vue' +import CodeEdit from '@/components/CodeEdit/CodeEdit.vue' import Convert from './convert.js' import { KeyValue, BODY_TYPE } from './ApiTestModel.js' export interface ApiBodyItem { diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/webhook/WebhookApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/WebhookApi.java index 8eb3d88c08..8df03663d1 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/webhook/WebhookApi.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/WebhookApi.java @@ -5,6 +5,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiSupport; import io.dataease.api.webhook.request.WebhookSwitchRequest; import io.dataease.api.webhook.vo.WebhookGridVO; import io.dataease.api.webhook.vo.WebhookOption; +import io.dataease.api.webhook.vo.WebhookVO; import io.dataease.model.KeywordRequest; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -33,7 +34,7 @@ public interface WebhookApi { @Operation(summary = "保存") @PostMapping("/save") - void save(@RequestBody WebhookGridVO creator); + void save(@RequestBody WebhookVO creator); @Operation(summary = "切换SSL") @PostMapping("/switchSsl") @@ -43,6 +44,10 @@ public interface WebhookApi { @PostMapping("/delete") void delete(@RequestBody List ids); + @Operation(summary = "查询详情") + @GetMapping("/get/{id}") + WebhookVO get(@PathVariable("id") Long id); + @Operation(summary = "查询选项") @GetMapping("/options") List options(); diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookGridVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookGridVO.java index 186016af92..b657e631b3 100644 --- a/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookGridVO.java +++ b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookGridVO.java @@ -24,9 +24,4 @@ public class WebhookGridVO implements Serializable { private String contentType; private Boolean ssl; - - @JsonSerialize(using= ToStringSerializer.class) - private Long oid; - - private Long createTime; } diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookVO.java new file mode 100644 index 0000000000..74e4db6c77 --- /dev/null +++ b/sdk/api/api-base/src/main/java/io/dataease/api/webhook/vo/WebhookVO.java @@ -0,0 +1,34 @@ +package io.dataease.api.webhook.vo; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +public class WebhookVO implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @JsonSerialize(using = ToStringSerializer.class) + private Long id; + + private String name; + + private String url; + + private String secret; + + private String contentType; + + private Boolean ssl; + + private String msgTemplate; + + @JsonSerialize(using = ToStringSerializer.class) + private Long oid; + + private Long createTime; +} diff --git a/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java b/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java index d2f962a6d5..990db0d663 100755 --- a/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java +++ b/sdk/common/src/main/java/io/dataease/utils/HttpClientUtil.java @@ -717,6 +717,39 @@ public class HttpClientUtil { } } + public static String postRawBody(String url, String contentType, String body, boolean ssl, HttpClientConfig config) { + CloseableHttpClient httpClient = null; + try { + httpClient = buildHttpClient(ssl); + HttpPost httpPost = new HttpPost(url); + if (ObjectUtils.isEmpty(config)) { + config = new HttpClientConfig(); + } + httpPost.setConfig(config.buildRequestConfig()); + Map header = config.getHeader(); + for (String key : header.keySet()) { + httpPost.addHeader(key, header.get(key)); + } + EntityBuilder entityBuilder = EntityBuilder.create(); + entityBuilder.setText(body); + entityBuilder.setContentType(ContentType.create(contentType, java.nio.charset.StandardCharsets.UTF_8)); + httpPost.setEntity(entityBuilder.build()); + HttpResponse response = httpClient.execute(httpPost); + return getResponseStr(response, config); + } catch (Exception e) { + logger.error("HttpClient POST raw body failed", e); + throw new DEException(SYSTEM_INNER_ERROR.code(), "HttpClient POST raw body failed: " + e.getMessage()); + } finally { + try { + if (httpClient != null) { + httpClient.close(); + } + } catch (Exception e) { + logger.error("HttpClient关闭连接失败", e); + } + } + } + public static MultipartResponse postForScreenshot( String url, Map body, HttpClientConfig config) throws IOException { CloseableHttpClient httpClient = null;