Explorar el Código

feat: 新增流程审批节点

jiaxing.liao hace 3 semanas
padre
commit
dd3b3ba37c

+ 13 - 0
apps/web/src/i18n/locales/en-us.ts

@@ -1442,6 +1442,15 @@ export default {
 			keyPlaceholder: 'Enter a specified id',
 			pathRequired: 'Please enter the basic dataset path'
 		},
+		workflowApprovalSetter: {
+			basicConfig: 'Approval Config',
+			usn: 'User Account',
+			usnPlaceholder: 'User account / phone / email',
+			jobId: 'Job ID',
+			jobIdPlaceholder: 'Enter job id',
+			workflowCode: 'Workflow Code',
+			workflowCodePlaceholder: 'Enter workflow code'
+		},
 		viewDataSetter: {
 			basicConfig: 'View Config',
 			code: 'View Name',
@@ -1590,6 +1599,10 @@ export default {
 			'sms-sender': {
 				displayName: 'SMS Sender',
 				description: 'Send SMS messages to specified phone numbers'
+			},
+			'workflow-approval': {
+				displayName: 'Workflow Approval',
+				description: 'Submit workflow approval request with user and job information'
 			}
 		},
 		outputs: {

+ 11 - 1
apps/web/src/i18n/locales/zh-cn.ts

@@ -1321,6 +1321,15 @@ export default {
 			keyPlaceholder: '请输入指定的 ID',
 			pathRequired: '请输入基础数据集路径'
 		},
+		workflowApprovalSetter: {
+			basicConfig: '审批配置',
+			usn: '用户账号',
+			usnPlaceholder: '用户账号/手机号/邮箱',
+			jobId: '岗位ID',
+			jobIdPlaceholder: '请输入岗位id',
+			workflowCode: '流程编号',
+			workflowCodePlaceholder: '请输入流程编号'
+		},
 		viewDataSetter: {
 			basicConfig: '视图配置',
 			code: '视图名称',
@@ -1462,7 +1471,8 @@ export default {
 			'iteration-start': { displayName: '迭代开始' },
 			stickyNote: { displayName: '注释', description: 'Markdown 注释块' },
 			'mail-sender': { displayName: '邮件发送', description: '通过邮件发送信息' },
-			'sms-sender': { displayName: '短信发送', description: '通过短信发送信息' }
+			'sms-sender': { displayName: '短信发送', description: '通过短信发送信息' },
+			'workflow-approval': { displayName: '流程审批', description: '根据用户和岗位信息发起流程审批' }
 		},
 		outputs: {
 			http: {

+ 1 - 0
apps/web/src/nodes/i18n.ts

@@ -20,6 +20,7 @@ const NODE_GROUP_KEYS: Record<string, 'start' | 'logic' | 'data' | 'tool' | 'oth
 	'trigger-webhook': 'start',
 	'mail-sender': 'tool',
 	'sms-sender': 'tool',
+	'workflow-approval': 'logic',
 	'loop-start': 'logic',
 	'iteration-start': 'logic',
 	stickyNote: 'other'

+ 3 - 1
apps/web/src/nodes/src/index.ts

@@ -16,6 +16,7 @@ import { basicDatasetNode } from './basic-dataset'
 import { viewDataNode } from './view-data'
 import { smsSenderNode } from './sms-sender'
 import { mailSenderNode } from './mail-sender'
+import { workflowApprovalNode } from './workflow-approval'
 
 import { getNodeDisplayName } from '@/nodes/i18n'
 import type { INodeType } from '../Interface'
@@ -121,7 +122,8 @@ const baseNodes = [
 	basicDatasetNode,
 	viewDataNode,
 	smsSenderNode,
-	mailSenderNode
+	mailSenderNode,
+	workflowApprovalNode
 ]
 
 const nodes = baseNodes.map((node) => withFailBranchOutput(node))

+ 1 - 2
apps/web/src/nodes/src/sms-sender/index.ts

@@ -1,13 +1,12 @@
 import { NodeConnectionTypes, type INodeDataBaseSchema, type INodeType } from '../../Interface'
 import Setter from './setter.vue'
-import i18n from '@/i18n'
 import { getNodeDescription, getNodeDisplayName } from '@/nodes/i18n'
 
 export type SMSSenderData = INodeDataBaseSchema & {
 	config_name: string // '�置�称'
 	sign_name: string // '签�'
 	template_code: string // '模版编�'
-	senders: string // '��者,多个�分割'
+	senders: string // '��者,多个�称用,分割'
 }
 
 export const smsSenderNode: INodeType = {

+ 44 - 0
apps/web/src/nodes/src/workflow-approval/index.ts

@@ -0,0 +1,44 @@
+import { NodeConnectionTypes, type INodeDataBaseSchema, type INodeType } from '../../Interface'
+import Setter from './setter.vue'
+import { getNodeDescription, getNodeDisplayName } from '@/nodes/i18n'
+
+export type WorkflowApprovalData = INodeDataBaseSchema & {
+	usn: string
+	jobId: string
+	workflowCode: string
+}
+
+export const workflowApprovalNode: INodeType = {
+	version: ['1'],
+	displayName: getNodeDisplayName('workflow-approval'),
+	name: 'workflow-approval',
+	Setter,
+	description: getNodeDescription('workflow-approval'),
+	group: 'logic',
+	icon: 'lucide:clipboard-check',
+	iconColor: '#f97316',
+	inputs: [NodeConnectionTypes.main],
+	outputs: [NodeConnectionTypes.main],
+	getSubtitle: (data: WorkflowApprovalData) => {
+		return data?.workflowCode ? `workflow: ${data.workflowCode}` : ''
+	},
+	schema: {
+		appAgentId: '',
+		parentId: '',
+		position: {
+			x: 20,
+			y: 30
+		},
+		width: 96,
+		height: 96,
+		selected: false,
+		nodeType: 'workflow-approval',
+		zIndex: 1,
+		data: {
+			usn: '用户账号/手机号/邮箱',
+			jobId: '岗位id',
+			workflowCode: '流程编号'
+		}
+	}
+}
+

+ 84 - 0
apps/web/src/nodes/src/workflow-approval/setter.vue

@@ -0,0 +1,84 @@
+<template>
+	<el-scrollbar class="w-full box-border p-12px">
+		<div class="workflow-approval-setter">
+			<section class="section-block">
+				<div class="section-title">{{ texts.basicConfig }}</div>
+
+				<el-form label-position="top">
+					<el-form-item :label="texts.usn">
+						<VarInput v-model="formData.usn" :placeholder="texts.usnPlaceholder" class="w-full" />
+					</el-form-item>
+
+					<el-form-item :label="texts.jobId">
+						<VarInput
+							v-model="formData.jobId"
+							:placeholder="texts.jobIdPlaceholder"
+							class="w-full"
+						/>
+					</el-form-item>
+
+					<el-form-item :label="texts.workflowCode">
+						<VarInput
+							v-model="formData.workflowCode"
+							:placeholder="texts.workflowCodePlaceholder"
+							class="w-full"
+						/>
+					</el-form-item>
+				</el-form>
+			</section>
+
+			<NodeRuntimeConfig v-model="formData" />
+		</div>
+	</el-scrollbar>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+
+import NodeRuntimeConfig from '@/nodes/_base/NodeRuntimeConfig.vue'
+import VarInput from '@/nodes/_base/VarInput.vue'
+import { useI18n } from '@/composables/useI18n'
+import { useSetterModel } from '../_shared/useSetterModel'
+import type { WorkflowApprovalData } from './index'
+
+interface Emits {
+	(e: 'update', value: WorkflowApprovalData): void
+}
+
+const props = defineProps<{
+	data: WorkflowApprovalData
+}>()
+
+const emit = defineEmits<Emits>()
+const { t } = useI18n()
+const formData = useSetterModel<WorkflowApprovalData>(props, emit)
+
+const texts = computed(() => ({
+	basicConfig: t('pages.workflowApprovalSetter.basicConfig'),
+	usn: t('pages.workflowApprovalSetter.usn'),
+	usnPlaceholder: t('pages.workflowApprovalSetter.usnPlaceholder'),
+	jobId: t('pages.workflowApprovalSetter.jobId'),
+	jobIdPlaceholder: t('pages.workflowApprovalSetter.jobIdPlaceholder'),
+	workflowCode: t('pages.workflowApprovalSetter.workflowCode'),
+	workflowCodePlaceholder: t('pages.workflowApprovalSetter.workflowCodePlaceholder')
+}))
+</script>
+
+<style scoped lang="less">
+.workflow-approval-setter {
+	display: flex;
+	flex-direction: column;
+	gap: 16px;
+}
+
+.section-block {
+	padding-bottom: 16px;
+}
+
+.section-title {
+	margin-bottom: 12px;
+	font-size: 14px;
+	font-weight: 700;
+	color: #374151;
+}
+</style>