From 69831144fbc3ed5adf1963bf2bc8d48f2035e010 Mon Sep 17 00:00:00 2001 From: beihai Date: Wed, 29 Oct 2025 09:57:55 +0800 Subject: [PATCH 01/16] =?UTF-8?q?feat:bpmn=E6=B5=81=E7=A8=8B=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=99=A8=E5=A2=9E=E5=8A=A0http=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer/plugins/palette/CustomPalette.js | 29 ++ .../plugins/palette/paletteProvider.js | 29 ++ .../package/designer/plugins/translate/zh.js | 1 + .../task/task-components/ServiceTask.vue | 271 ++++++++++++++++-- 4 files changed, 312 insertions(+), 18 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js index 788e4d16..8bdbcfca 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js @@ -89,6 +89,26 @@ F.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } + function createHttpServiceTask(event) { + const httpTask = elementFactory.createShape({ + type: 'bpmn:ServiceTask' + }) + + const businessObject = httpTask.businessObject + + if (typeof businessObject.set === 'function') { + businessObject.set('flowable:type', 'http') + } else { + businessObject['flowable:type'] = 'http' + } + + if (!businessObject.name) { + businessObject.name = translate('HTTP Task') + } + + create.start(event, httpTask) + } + assign(actions, { 'hand-tool': { group: 'tools', @@ -177,6 +197,15 @@ F.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), + 'create.http-service-task': { + group: 'activity', + className: 'bpmn-icon-service', + title: translate('Create HTTP Task'), + action: { + dragstart: createHttpServiceTask, + click: createHttpServiceTask + } + }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js index 304875ce..e9cb2d31 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js @@ -96,6 +96,26 @@ PaletteProvider.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } + function createHttpServiceTask(event) { + const httpTask = elementFactory.createShape({ + type: 'bpmn:ServiceTask' + }) + + const businessObject = httpTask.businessObject + + if (typeof businessObject.set === 'function') { + businessObject.set('flowable:type', 'http') + } else { + businessObject['flowable:type'] = 'http' + } + + if (!businessObject.name) { + businessObject.name = translate('HTTP Task') + } + + create.start(event, httpTask) + } + assign(actions, { 'hand-tool': { group: 'tools', @@ -177,6 +197,15 @@ PaletteProvider.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), + 'create.http-service-task': { + group: 'activity', + className: 'bpmn-icon-service', + title: translate('Create HTTP Task'), + action: { + dragstart: createHttpServiceTask, + click: createHttpServiceTask + } + }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/translate/zh.js b/src/components/bpmnProcessDesigner/package/designer/plugins/translate/zh.js index d243ec45..4ac5bb5c 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/translate/zh.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/translate/zh.js @@ -43,6 +43,7 @@ export default { 'Manual Task': '手工任务', 'Business Rule Task': '业务规则任务', 'Service Task': '服务任务', + 'HTTP Task': 'HTTP任务', 'Script Task': '脚本任务', 'Call Activity': '调用活动', 'Sub-Process (collapsed)': '子流程(折叠的)', diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index 2f9c535e..cc4d2abf 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -1,10 +1,11 @@ From 50c7d4798436bde5a1221677c6bbf2ebcc7056c8 Mon Sep 17 00:00:00 2001 From: sinkingsoul <286447685@qq.com> Date: Fri, 31 Oct 2025 17:07:31 +0800 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=E5=88=A0=E9=99=A4http=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=BB=84=E4=BB=B6=E5=9B=BE=E6=A0=87=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E6=88=90=E6=9C=8D=E5=8A=A1=E4=BB=BB=E5=8A=A1=E7=9A=84=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E7=B1=BB=E5=9E=8B=E4=B8=8B=E6=8B=89=E6=A1=86=E4=B8=AD?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer/plugins/palette/CustomPalette.js | 28 ------------------- .../plugins/palette/paletteProvider.js | 28 ------------------- 2 files changed, 56 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js index 8bdbcfca..12683871 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/CustomPalette.js @@ -89,25 +89,6 @@ F.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } - function createHttpServiceTask(event) { - const httpTask = elementFactory.createShape({ - type: 'bpmn:ServiceTask' - }) - - const businessObject = httpTask.businessObject - - if (typeof businessObject.set === 'function') { - businessObject.set('flowable:type', 'http') - } else { - businessObject['flowable:type'] = 'http' - } - - if (!businessObject.name) { - businessObject.name = translate('HTTP Task') - } - - create.start(event, httpTask) - } assign(actions, { 'hand-tool': { @@ -197,15 +178,6 @@ F.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), - 'create.http-service-task': { - group: 'activity', - className: 'bpmn-icon-service', - title: translate('Create HTTP Task'), - action: { - dragstart: createHttpServiceTask, - click: createHttpServiceTask - } - }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', diff --git a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js index e9cb2d31..8a585888 100644 --- a/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js +++ b/src/components/bpmnProcessDesigner/package/designer/plugins/palette/paletteProvider.js @@ -96,25 +96,6 @@ PaletteProvider.prototype.getPaletteEntries = function () { create.start(event, elementFactory.createParticipantShape()) } - function createHttpServiceTask(event) { - const httpTask = elementFactory.createShape({ - type: 'bpmn:ServiceTask' - }) - - const businessObject = httpTask.businessObject - - if (typeof businessObject.set === 'function') { - businessObject.set('flowable:type', 'http') - } else { - businessObject['flowable:type'] = 'http' - } - - if (!businessObject.name) { - businessObject.name = translate('HTTP Task') - } - - create.start(event, httpTask) - } assign(actions, { 'hand-tool': { @@ -197,15 +178,6 @@ PaletteProvider.prototype.getPaletteEntries = function () { 'bpmn-icon-service', translate('Create Service Task') ), - 'create.http-service-task': { - group: 'activity', - className: 'bpmn-icon-service', - title: translate('Create HTTP Task'), - action: { - dragstart: createHttpServiceTask, - click: createHttpServiceTask - } - }, 'create.data-object': createAction( 'bpmn:DataObjectReference', 'data-object', From d04a30fe41f0b6da0e79030c3019df5969b9eb46 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 25 Nov 2025 11:31:47 +0800 Subject: [PATCH 03/16] typo --- .../package/penal/task/task-components/ServiceTask.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index cc4d2abf..37573c8c 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -1,6 +1,6 @@ @@ -94,12 +100,15 @@ const HTTP_FIELD_NAMES = [ 'requestHeaders', 'disallowRedirects', 'ignoreException', + 'saveResponseParameters', + 'resultVariablePrefix', 'saveResponseParametersTransient', 'saveResponseVariableAsJson' ] const HTTP_BOOLEAN_FIELDS = new Set([ 'disallowRedirects', 'ignoreException', + 'saveResponseParameters', 'saveResponseParametersTransient', 'saveResponseVariableAsJson' ]) @@ -115,8 +124,10 @@ const DEFAULT_HTTP_FORM = { requestMethod: 'GET', requestUrl: '', requestHeaders: 'Content-Type: application/json', + resultVariablePrefix: '', disallowRedirects: false, ignoreException: false, + saveResponseParameters: false, saveResponseParametersTransient: false, saveResponseVariableAsJson: false } From c50e0dee8c76d6eea04b0121f1cd69dbf9037300 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 18 Nov 2025 11:40:58 +0800 Subject: [PATCH 06/16] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DHTTP=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=B8=AD=E8=AF=B7=E6=B1=82=E5=A4=B4=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E4=BD=BF=E7=94=A8EL=E8=A1=A8=E8=BE=BE=E5=BC=8F=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/task-components/ServiceTask.vue | 51 ++++++++++++++----- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index eda9168e..3c8e37e3 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -139,22 +139,32 @@ const httpInitializing = ref(false) const bpmnInstances = () => (window as any)?.bpmnInstances +// 判断字符串是否包含表达式 +const isExpression = (value: string): boolean => { + if (!value) return false + // 检测 ${...} 或 #{...} 格式的表达式 + return /\${[^}]+}/.test(value) || /#{[^}]+}/.test(value) +} + const collectHttpExtensionInfo = () => { const businessObject = bpmnElement.value?.businessObject const extensionElements = businessObject?.extensionElements const httpFields = new Map() + const httpFieldTypes = new Map() const otherExtensions: any[] = [] extensionElements?.values?.forEach((item: any) => { if (item?.$type === flowableFieldType && HTTP_FIELD_NAMES.includes(item.name)) { const value = item.string ?? item.stringValue ?? item.expression ?? '' + const fieldType = item.expression ? 'expression' : 'string' httpFields.set(item.name, value) + httpFieldTypes.set(item.name, fieldType) } else { otherExtensions.push(item) } }) - return { httpFields, otherExtensions } + return { httpFields, httpFieldTypes, otherExtensions } } const resetHttpDefaults = () => { @@ -168,7 +178,7 @@ const resetHttpDefaults = () => { const resetHttpForm = () => { httpInitializing.value = true const { httpFields } = collectHttpExtensionInfo() - const nextForm: Record = { ...DEFAULT_HTTP_FORM } + const nextForm = { ...DEFAULT_HTTP_FORM } HTTP_FIELD_NAMES.forEach((name) => { const stored = httpFields.get(name) @@ -228,7 +238,11 @@ const updateHttpExtensions = (force = false) => { return } - const { httpFields: existingFields, otherExtensions } = collectHttpExtensionInfo() + const { + httpFields: existingFields, + httpFieldTypes: existingTypes, + otherExtensions + } = collectHttpExtensionInfo() const desiredEntries: [string, string][] = [] HTTP_FIELD_NAMES.forEach((name) => { @@ -246,21 +260,32 @@ const updateHttpExtensions = (force = false) => { desiredEntries.push([name, persisted]) }) - if ( - !force && - desiredEntries.length === existingFields.size && - desiredEntries.every(([name, value]) => existingFields.get(name) === value) - ) { - return + // 检查是否有变化:不仅比较值,还要比较字段类型(string vs expression) + if (!force && desiredEntries.length === existingFields.size) { + let noChange = true + for (const [name, value] of desiredEntries) { + const existingValue = existingFields.get(name) + const existingType = existingTypes.get(name) + const currentType = isExpression(value) ? 'expression' : 'string' + if (existingValue !== value || existingType !== currentType) { + noChange = false + break + } + } + if (noChange) { + return + } } const moddle = bpmnInstances().moddle - const httpFieldElements = desiredEntries.map(([name, value]) => - moddle.create(flowableFieldType, { + const httpFieldElements = desiredEntries.map(([name, value]) => { + // 根据值是否包含表达式来决定使用 string 还是 expression 属性 + const isExpr = isExpression(value) + return moddle.create(flowableFieldType, { name, - string: value + ...(isExpr ? { expression: value } : { string: value }) }) - ) + }) updateElementExtensions(bpmnElement.value, [...otherExtensions, ...httpFieldElements]) } From d66cd5d209c52ab565b53cd3806028a1a2bd7b24 Mon Sep 17 00:00:00 2001 From: zhanglc Date: Tue, 18 Nov 2025 14:52:42 +0800 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96HTTP=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=AF=B7=E6=B1=82=E5=A4=B4=E8=BE=93=E5=85=A5=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E9=94=AE=E5=80=BC=E5=AF=B9=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/task-components/HttpHeaderEditor.vue | 178 ++++++++++++++++++ .../task/task-components/ServiceTask.vue | 55 ++++-- 2 files changed, 219 insertions(+), 14 deletions(-) create mode 100644 src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue new file mode 100644 index 00000000..5d0a1334 --- /dev/null +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/HttpHeaderEditor.vue @@ -0,0 +1,178 @@ + + + + + diff --git a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue index 3c8e37e3..642c3c28 100644 --- a/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue +++ b/src/components/bpmnProcessDesigner/package/penal/task/task-components/ServiceTask.vue @@ -43,22 +43,34 @@ - - - + + + - +
+ + + 编辑 + +
@@ -66,24 +78,34 @@ - + - + - + - + + + +