1
This commit is contained in:
parent
3542ca7a7c
commit
8e5e97cb95
@ -17,6 +17,7 @@
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-avatar": "^1.1.2",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||
"@radix-ui/react-label": "^2.1.1",
|
||||
@ -31,6 +32,10 @@
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-toast": "^1.2.4",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@react-form-builder/components-rsuite": "^7.4.0",
|
||||
"@react-form-builder/core": "^7.4.0",
|
||||
"@react-form-builder/designer": "^7.4.0",
|
||||
"@react-form-builder/designer-bundle": "^7.4.0",
|
||||
"@reduxjs/toolkit": "^2.0.1",
|
||||
"@types/recharts": "^1.8.29",
|
||||
"@types/uuid": "^10.0.0",
|
||||
@ -42,6 +47,8 @@
|
||||
"cmdk": "^1.0.4",
|
||||
"dagre": "^0.8.5",
|
||||
"dayjs": "^1.11.13",
|
||||
"form-render": "^2.5.6",
|
||||
"generator-form": "^0.2.0",
|
||||
"less": "^4.2.1",
|
||||
"monaco-editor": "^0.52.2",
|
||||
"react": "^18.2.0",
|
||||
@ -51,6 +58,7 @@
|
||||
"react-redux": "^9.0.4",
|
||||
"react-router-dom": "^6.21.0",
|
||||
"recharts": "^2.15.0",
|
||||
"rsuite": "^5.83.3",
|
||||
"uuid": "^13.0.0",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
|
||||
28
frontend/src/components/ui/checkbox.tsx
Normal file
28
frontend/src/components/ui/checkbox.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import * as React from "react"
|
||||
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
|
||||
import { Check } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Checkbox = React.forwardRef<
|
||||
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<CheckboxPrimitive.Indicator
|
||||
className={cn("grid place-content-center text-current")}
|
||||
>
|
||||
<Check className="h-4 w-4" />
|
||||
</CheckboxPrimitive.Indicator>
|
||||
</CheckboxPrimitive.Root>
|
||||
))
|
||||
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
||||
|
||||
export { Checkbox }
|
||||
@ -9,6 +9,7 @@ import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, For
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import type { FlowNode, FlowNodeData, FlowEdge } from '../types';
|
||||
import type { WorkflowNodeDefinition, JSONSchema } from '../nodes/types';
|
||||
@ -232,6 +233,36 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||
});
|
||||
};
|
||||
|
||||
// ✅ 条件评估函数(支持 x-condition)
|
||||
const evaluateCondition = useCallback((
|
||||
currentValue: any,
|
||||
expectedValue: any,
|
||||
operator: string = '==='
|
||||
): boolean => {
|
||||
switch (operator) {
|
||||
case '===':
|
||||
case '==':
|
||||
return currentValue === expectedValue;
|
||||
case '!==':
|
||||
case '!=':
|
||||
return currentValue !== expectedValue;
|
||||
case '>':
|
||||
return Number(currentValue) > Number(expectedValue);
|
||||
case '<':
|
||||
return Number(currentValue) < Number(expectedValue);
|
||||
case '>=':
|
||||
return Number(currentValue) >= Number(expectedValue);
|
||||
case '<=':
|
||||
return Number(currentValue) <= Number(expectedValue);
|
||||
case 'includes':
|
||||
return Array.isArray(currentValue) && currentValue.includes(expectedValue);
|
||||
case 'notIncludes':
|
||||
return Array.isArray(currentValue) && !currentValue.includes(expectedValue);
|
||||
default:
|
||||
return currentValue === expectedValue;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// ✅ 通用 Select 渲染函数(减少代码重复)
|
||||
const renderSelect = useCallback((
|
||||
options: Array<{ label: string; value: any }>,
|
||||
@ -352,13 +383,13 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||
|
||||
case 'boolean':
|
||||
return (
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={field.value || false}
|
||||
disabled={loading}
|
||||
onChange={(e) => field.onChange(e.target.checked)}
|
||||
className="h-4 w-4"
|
||||
/>
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
checked={field.value || false}
|
||||
disabled={loading}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
default:
|
||||
@ -372,8 +403,8 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||
}
|
||||
}, [dataSourceCache, loadingDataSources, loading, node, renderSelect]);
|
||||
|
||||
// ✅ 渲染表单字段
|
||||
const renderFormFields = useCallback((
|
||||
// ✅ 渲染表单字段(不使用 useCallback 以支持 watch 的响应式更新)
|
||||
const renderFormFields = (
|
||||
schema: JSONSchema,
|
||||
form: ReturnType<typeof useForm>,
|
||||
prefix: string = ''
|
||||
@ -386,6 +417,22 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||
const fieldName = prefix ? `${prefix}.${key}` : key;
|
||||
const isRequired = Array.isArray(schema.required) && schema.required.includes(key);
|
||||
|
||||
// ✅ 检查条件显示(x-condition)- 使用 watch 订阅字段变化
|
||||
if (prop['x-condition']) {
|
||||
const condition = prop['x-condition'];
|
||||
const conditionField = condition.field;
|
||||
const conditionValue = condition.value;
|
||||
const conditionOperator = condition.operator || '===';
|
||||
|
||||
// 获取条件字段的当前值(watch 会订阅该字段的变化,触发组件重新渲染)
|
||||
const currentFieldValue = form.watch(conditionField);
|
||||
|
||||
// 评估条件,如果不满足则不渲染该字段
|
||||
if (!evaluateCondition(currentFieldValue, conditionValue, conditionOperator)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FormField
|
||||
key={fieldName}
|
||||
@ -409,7 +456,7 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||
/>
|
||||
);
|
||||
});
|
||||
}, [renderFieldControl]);
|
||||
};
|
||||
|
||||
if (!nodeDefinition) {
|
||||
return null;
|
||||
|
||||
228
frontend/src/pages/Workflow/Design/nodes/ApprovalNode.tsx
Normal file
228
frontend/src/pages/Workflow/Design/nodes/ApprovalNode.tsx
Normal file
@ -0,0 +1,228 @@
|
||||
import {ConfigurableNodeDefinition, NodeType, NodeCategory, defineNodeOutputs} from './types';
|
||||
import {DataSourceType} from '../utils/dataSourceLoader';
|
||||
|
||||
/**
|
||||
* 审批节点定义
|
||||
* 用于人工审批流程,支持单人审批、多人会签、多人或签等模式
|
||||
*/
|
||||
export const ApprovalNodeDefinition: ConfigurableNodeDefinition = {
|
||||
nodeCode: "APPROVAL",
|
||||
nodeName: "审批节点",
|
||||
nodeType: NodeType.APPROVAL,
|
||||
category: NodeCategory.TASK,
|
||||
description: "人工审批节点,支持多种审批模式",
|
||||
|
||||
// 渲染配置
|
||||
renderConfig: {
|
||||
shape: 'rounded-rect',
|
||||
size: {width: 140, height: 48},
|
||||
icon: {
|
||||
type: 'emoji',
|
||||
content: '✅',
|
||||
size: 32
|
||||
},
|
||||
theme: {
|
||||
primary: '#10b981',
|
||||
secondary: '#059669',
|
||||
selectedBorder: '#3b82f6',
|
||||
hoverBorder: '#10b981',
|
||||
gradient: ['#ffffff', '#d1fae5']
|
||||
},
|
||||
handles: {
|
||||
input: true,
|
||||
output: true
|
||||
},
|
||||
features: {
|
||||
showBadge: true,
|
||||
showHoverMenu: true
|
||||
}
|
||||
},
|
||||
|
||||
// 输入配置Schema
|
||||
inputMappingSchema: {
|
||||
type: "object",
|
||||
title: "审批配置",
|
||||
description: "配置审批人和审批规则",
|
||||
properties: {
|
||||
approvalMode: {
|
||||
type: "string",
|
||||
title: "审批模式",
|
||||
description: "单人审批:仅需一人审批;会签:所有审批人都必须同意;或签:任一审批人同意即可",
|
||||
enum: ["SINGLE", "ALL", "ANY"],
|
||||
enumNames: ["单人审批", "会签(所有人同意)", "或签(任一人同意)"],
|
||||
default: "SINGLE"
|
||||
},
|
||||
approverType: {
|
||||
type: "string",
|
||||
title: "审批人类型",
|
||||
description: "指定审批人的方式:用户(选中的用户)、角色(拥有该角色的所有用户)、部门(该部门的所有成员)、变量(流程变量)",
|
||||
enum: ["USER", "ROLE", "DEPARTMENT", "VARIABLE"],
|
||||
enumNames: ["指定用户", "指定角色", "指定部门", "流程变量"],
|
||||
default: "USER"
|
||||
},
|
||||
approvers: {
|
||||
type: "array",
|
||||
title: "审批人列表",
|
||||
description: "选择具体的审批人。会签模式下:选中的所有用户都必须审批;或签模式下:任一用户审批即可",
|
||||
items: {
|
||||
type: "number"
|
||||
},
|
||||
'x-dataSource': DataSourceType.USERS,
|
||||
'x-condition': {
|
||||
field: 'approverType',
|
||||
value: 'USER'
|
||||
}
|
||||
},
|
||||
approverRoles: {
|
||||
type: "array",
|
||||
title: "审批角色",
|
||||
description: "选择审批角色。会签模式下:拥有选中角色的所有用户都必须审批;或签模式下:任一拥有该角色的用户审批即可",
|
||||
items: {
|
||||
type: "number"
|
||||
},
|
||||
'x-dataSource': DataSourceType.ROLES,
|
||||
'x-condition': {
|
||||
field: 'approverType',
|
||||
value: 'ROLE'
|
||||
}
|
||||
},
|
||||
approverDepartments: {
|
||||
type: "array",
|
||||
title: "审批部门",
|
||||
description: "选择审批部门。会签模式下:选中部门的所有成员都必须审批;或签模式下:任一部门成员审批即可",
|
||||
items: {
|
||||
type: "number"
|
||||
},
|
||||
'x-dataSource': DataSourceType.DEPARTMENTS,
|
||||
'x-condition': {
|
||||
field: 'approverType',
|
||||
value: 'DEPARTMENT'
|
||||
}
|
||||
},
|
||||
approverVariable: {
|
||||
type: "string",
|
||||
title: "审批人变量",
|
||||
description: "使用流程变量指定审批人(格式:${变量名})",
|
||||
'x-condition': {
|
||||
field: 'approverType',
|
||||
value: 'VARIABLE'
|
||||
}
|
||||
},
|
||||
approvalTitle: {
|
||||
type: "string",
|
||||
title: "审批标题",
|
||||
description: "审批任务的标题,支持变量",
|
||||
default: "待审批:${工作流实例.title}"
|
||||
},
|
||||
approvalContent: {
|
||||
type: "string",
|
||||
title: "审批内容",
|
||||
description: "审批任务的详细说明,支持变量",
|
||||
'x-component': "textarea"
|
||||
},
|
||||
timeoutDuration: {
|
||||
type: "number",
|
||||
title: "超时时间(小时)",
|
||||
description: "审批超时时间,0表示不限制",
|
||||
default: 0,
|
||||
minimum: 0
|
||||
},
|
||||
timeoutAction: {
|
||||
type: "string",
|
||||
title: "超时处理",
|
||||
description: "审批超时后的处理方式",
|
||||
enum: ["NONE", "AUTO_APPROVE", "AUTO_REJECT", "NOTIFY"],
|
||||
enumNames: ["无操作", "自动通过", "自动拒绝", "仅通知"],
|
||||
default: "NONE",
|
||||
'x-condition': {
|
||||
field: 'timeoutDuration',
|
||||
operator: '>',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
allowDelegate: {
|
||||
type: "boolean",
|
||||
title: "允许转交",
|
||||
description: "是否允许审批人转交给其他人",
|
||||
default: false
|
||||
},
|
||||
allowAddSign: {
|
||||
type: "boolean",
|
||||
title: "允许加签",
|
||||
description: "是否允许审批人加签",
|
||||
default: false
|
||||
},
|
||||
requireComment: {
|
||||
type: "boolean",
|
||||
title: "必须填写意见",
|
||||
description: "审批时是否必须填写审批意见",
|
||||
default: false
|
||||
}
|
||||
},
|
||||
required: ["approvalMode", "approverType", "approvalTitle"]
|
||||
},
|
||||
|
||||
// 输出配置
|
||||
outputs: defineNodeOutputs(
|
||||
{
|
||||
name: "approvalResult",
|
||||
title: "审批结果",
|
||||
type: "string",
|
||||
enum: ["APPROVED", "REJECTED", "TIMEOUT"],
|
||||
description: "审批的最终结果",
|
||||
example: "APPROVED",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "approver",
|
||||
title: "审批人",
|
||||
type: "string",
|
||||
description: "实际执行审批的用户",
|
||||
example: "张三",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "approverUserId",
|
||||
title: "审批人ID",
|
||||
type: "number",
|
||||
description: "审批人的用户ID",
|
||||
example: 1001,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "approvalTime",
|
||||
title: "审批时间",
|
||||
type: "string",
|
||||
description: "审批完成的时间",
|
||||
example: "2025-10-23T10:30:00Z",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "approvalComment",
|
||||
title: "审批意见",
|
||||
type: "string",
|
||||
description: "审批人填写的意见",
|
||||
example: "同意发布到生产环境",
|
||||
required: false
|
||||
},
|
||||
{
|
||||
name: "approvalDuration",
|
||||
title: "审批用时(秒)",
|
||||
type: "number",
|
||||
description: "从创建到完成审批的时长",
|
||||
example: 3600,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "allApprovers",
|
||||
title: "所有审批人",
|
||||
type: "array",
|
||||
description: "参与审批的所有人员列表(会签/或签时),格式:[{userId, userName, result, comment, time}]",
|
||||
example: [{userId: 1001, userName: "张三", result: "APPROVED", comment: "同意", time: "2025-10-23T10:30:00Z"}],
|
||||
required: false
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
// ✅ 不再需要单独的渲染组件,使用 BaseNode 即可
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {ConfigurableNodeDefinition, NodeType, NodeCategory} from './types';
|
||||
import {ConfigurableNodeDefinition, NodeType, NodeCategory, defineNodeOutputs} from './types';
|
||||
import {DataSourceType} from '../utils/dataSourceLoader';
|
||||
|
||||
/**
|
||||
@ -59,7 +59,7 @@ export const JenkinsBuildNodeDefinition: ConfigurableNodeDefinition = {
|
||||
},
|
||||
required: ["jenkinsServerId"]
|
||||
},
|
||||
outputs: [
|
||||
outputs: defineNodeOutputs(
|
||||
{
|
||||
name: "buildNumber",
|
||||
title: "构建编号",
|
||||
@ -68,15 +68,6 @@ export const JenkinsBuildNodeDefinition: ConfigurableNodeDefinition = {
|
||||
example: 123,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
title: "构建状态",
|
||||
type: "string",
|
||||
enum: ["SUCCESS", "FAILURE"],
|
||||
description: "构建执行的结果状态",
|
||||
example: "SUCCESS",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "buildUrl",
|
||||
title: "构建URL",
|
||||
@ -109,7 +100,7 @@ export const JenkinsBuildNodeDefinition: ConfigurableNodeDefinition = {
|
||||
example: 120,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
)
|
||||
};
|
||||
|
||||
// ✅ 不再需要单独的渲染组件,使用 BaseNode 即可
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {ConfigurableNodeDefinition, NodeType, NodeCategory} from './types';
|
||||
import {ConfigurableNodeDefinition, NodeType, NodeCategory, defineNodeOutputs} from './types';
|
||||
import {DataSourceType} from "@/pages/Workflow/Design/utils/dataSourceLoader.ts";
|
||||
|
||||
/**
|
||||
@ -80,13 +80,6 @@ export const NotificationNodeDefinition: ConfigurableNodeDefinition = {
|
||||
},
|
||||
required: ["notificationChannel", "title", "content"]
|
||||
},
|
||||
outputs: [{
|
||||
name: "status",
|
||||
title: "执行状态",
|
||||
type: "string",
|
||||
enum: ["SUCCESS", "FAILURE"],
|
||||
description: "执行的结果状态",
|
||||
example: "SUCCESS"
|
||||
}]
|
||||
outputs: defineNodeOutputs()
|
||||
};
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import { StartEventNodeDefinition } from './StartEventNode';
|
||||
import { EndEventNodeDefinition } from './EndEventNode';
|
||||
import { JenkinsBuildNodeDefinition } from './JenkinsBuildNode';
|
||||
import { NotificationNodeDefinition } from './NotificationNode';
|
||||
import { ApprovalNodeDefinition } from './ApprovalNode';
|
||||
import type { WorkflowNodeDefinition } from './types';
|
||||
|
||||
/**
|
||||
@ -19,6 +20,7 @@ export const NODE_DEFINITIONS: WorkflowNodeDefinition[] = [
|
||||
EndEventNodeDefinition,
|
||||
JenkinsBuildNodeDefinition,
|
||||
NotificationNodeDefinition,
|
||||
ApprovalNodeDefinition,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -30,6 +32,7 @@ export const nodeTypes = {
|
||||
END_EVENT: BaseNode,
|
||||
JENKINS_BUILD: BaseNode,
|
||||
NOTIFICATION: BaseNode,
|
||||
APPROVAL: BaseNode,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -44,6 +47,7 @@ export {
|
||||
EndEventNodeDefinition,
|
||||
JenkinsBuildNodeDefinition,
|
||||
NotificationNodeDefinition,
|
||||
ApprovalNodeDefinition,
|
||||
};
|
||||
|
||||
// 导出类型
|
||||
|
||||
@ -16,6 +16,7 @@ export enum NodeType {
|
||||
DEPLOY_NODE = 'DEPLOY_NODE',
|
||||
JENKINS_BUILD = 'JENKINS_BUILD',
|
||||
NOTIFICATION = 'NOTIFICATION',
|
||||
APPROVAL = 'APPROVAL',
|
||||
GATEWAY_NODE = 'GATEWAY_NODE',
|
||||
SUB_PROCESS = 'SUB_PROCESS',
|
||||
CALL_ACTIVITY = 'CALL_ACTIVITY'
|
||||
@ -31,6 +32,7 @@ export const NODE_CATEGORY_MAP: Record<NodeType, NodeCategory> = {
|
||||
[NodeType.DEPLOY_NODE]: NodeCategory.TASK,
|
||||
[NodeType.JENKINS_BUILD]: NodeCategory.TASK,
|
||||
[NodeType.NOTIFICATION]: NodeCategory.TASK,
|
||||
[NodeType.APPROVAL]: NodeCategory.TASK,
|
||||
[NodeType.GATEWAY_NODE]: NodeCategory.GATEWAY,
|
||||
[NodeType.SUB_PROCESS]: NodeCategory.CONTAINER,
|
||||
[NodeType.CALL_ACTIVITY]: NodeCategory.CONTAINER,
|
||||
@ -84,6 +86,55 @@ export interface OutputField {
|
||||
required?: boolean; // 是否必定产生(默认 true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础输出字段 - 所有节点都会产生的通用字段
|
||||
* 类似于 Java 中的继承,每个节点都会自动拥有这些字段
|
||||
*/
|
||||
export const BASE_OUTPUT_FIELDS: OutputField[] = [
|
||||
{
|
||||
name: "status",
|
||||
title: "执行状态",
|
||||
type: "string",
|
||||
enum: ["SUCCESS", "FAILURE"],
|
||||
description: "节点执行的最终状态",
|
||||
example: "SUCCESS",
|
||||
required: true
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* 工具函数:定义节点输出字段
|
||||
* 类似于 Java 的继承,自动合并基础字段和节点特有字段
|
||||
*
|
||||
* @param customFields - 节点特有的输出字段
|
||||
* @returns 包含基础字段和自定义字段的完整输出列表
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* outputs: defineNodeOutputs(
|
||||
* {
|
||||
* name: "buildNumber",
|
||||
* title: "构建编号",
|
||||
* type: "number",
|
||||
* description: "Jenkins 构建编号",
|
||||
* example: 123,
|
||||
* required: true
|
||||
* },
|
||||
* {
|
||||
* name: "buildUrl",
|
||||
* title: "构建URL",
|
||||
* type: "string",
|
||||
* description: "Jenkins构建页面的访问地址",
|
||||
* example: "http://jenkins.example.com/job/app/123/",
|
||||
* required: true
|
||||
* }
|
||||
* )
|
||||
* ```
|
||||
*/
|
||||
export const defineNodeOutputs = (...customFields: OutputField[]): OutputField[] => {
|
||||
return [...BASE_OUTPUT_FIELDS, ...customFields];
|
||||
};
|
||||
|
||||
// ========== 渲染配置(配置驱动节点渲染) ==========
|
||||
|
||||
// 节点尺寸
|
||||
|
||||
@ -9,7 +9,10 @@ export enum DataSourceType {
|
||||
GIT_REPOSITORIES = 'GIT_REPOSITORIES',
|
||||
DOCKER_REGISTRIES = 'DOCKER_REGISTRIES',
|
||||
NOTIFICATION_CHANNEL_TYPES = 'NOTIFICATION_CHANNEL_TYPES',
|
||||
NOTIFICATION_CHANNELS = 'NOTIFICATION_CHANNELS'
|
||||
NOTIFICATION_CHANNELS = 'NOTIFICATION_CHANNELS',
|
||||
USERS = 'USERS',
|
||||
ROLES = 'ROLES',
|
||||
DEPARTMENTS = 'DEPARTMENTS'
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,6 +100,39 @@ export const DATA_SOURCE_REGISTRY: Record<DataSourceType, DataSourceConfig> = {
|
||||
url: item.url
|
||||
}));
|
||||
}
|
||||
},
|
||||
[DataSourceType.USERS]: {
|
||||
url: '/api/v1/system/users/page',
|
||||
params: {pageSize: 1000},
|
||||
transform: (data: any) => {
|
||||
const users = data.content || data;
|
||||
return users.map((item: any) => ({
|
||||
label: `${item.name} (${item.username})`,
|
||||
value: item.id,
|
||||
username: item.username,
|
||||
email: item.email
|
||||
}));
|
||||
}
|
||||
},
|
||||
[DataSourceType.ROLES]: {
|
||||
url: '/api/v1/system/roles/list',
|
||||
transform: (data: any[]) => {
|
||||
return data.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
code: item.code
|
||||
}));
|
||||
}
|
||||
},
|
||||
[DataSourceType.DEPARTMENTS]: {
|
||||
url: '/api/v1/system/departments/list',
|
||||
transform: (data: any[]) => {
|
||||
return data.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
code: item.code
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user