1
This commit is contained in:
parent
8e5e97cb95
commit
fc1d7da919
@ -22,7 +22,7 @@
|
|||||||
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
||||||
"@radix-ui/react-label": "^2.1.1",
|
"@radix-ui/react-label": "^2.1.1",
|
||||||
"@radix-ui/react-navigation-menu": "^1.2.3",
|
"@radix-ui/react-navigation-menu": "^1.2.3",
|
||||||
"@radix-ui/react-popover": "^1.1.4",
|
"@radix-ui/react-popover": "^1.1.15",
|
||||||
"@radix-ui/react-progress": "^1.1.1",
|
"@radix-ui/react-progress": "^1.1.1",
|
||||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||||
"@radix-ui/react-select": "^2.1.4",
|
"@radix-ui/react-select": "^2.1.4",
|
||||||
@ -44,7 +44,7 @@
|
|||||||
"ajv-formats": "^3.0.1",
|
"ajv-formats": "^3.0.1",
|
||||||
"antd": "^5.23.1",
|
"antd": "^5.23.1",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.6.2",
|
||||||
"cmdk": "^1.0.4",
|
"cmdk": "^1.1.1",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"form-render": "^2.5.6",
|
"form-render": "^2.5.6",
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||||
import { Command as CommandPrimitive } from "cmdk"
|
import { Command as CommandPrimitive } from "cmdk"
|
||||||
import { Search } from "lucide-react"
|
import { Search } from "lucide-react"
|
||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { Dialog, DialogContent } from "@/components/ui/dialog"
|
import { Dialog, DialogContent } from "@/components/ui/dialog"
|
||||||
import { type DialogProps } from "@radix-ui/react-dialog"
|
|
||||||
|
|
||||||
const Command = React.forwardRef<
|
const Command = React.forwardRef<
|
||||||
React.ElementRef<typeof CommandPrimitive>,
|
React.ElementRef<typeof CommandPrimitive>,
|
||||||
@ -20,12 +21,10 @@ const Command = React.forwardRef<
|
|||||||
))
|
))
|
||||||
Command.displayName = CommandPrimitive.displayName
|
Command.displayName = CommandPrimitive.displayName
|
||||||
|
|
||||||
interface CommandDialogProps extends DialogProps {}
|
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
||||||
|
|
||||||
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
|
|
||||||
return (
|
return (
|
||||||
<Dialog {...props}>
|
<Dialog {...props}>
|
||||||
<DialogContent className="overflow-hidden p-0 shadow-lg">
|
<DialogContent className="overflow-hidden p-0">
|
||||||
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||||
{children}
|
{children}
|
||||||
</Command>
|
</Command>
|
||||||
@ -43,7 +42,7 @@ const CommandInput = React.forwardRef<
|
|||||||
<CommandPrimitive.Input
|
<CommandPrimitive.Input
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@ -114,7 +113,7 @@ const CommandItem = React.forwardRef<
|
|||||||
<CommandPrimitive.Item
|
<CommandPrimitive.Item
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@ -10,6 +10,10 @@ import { Input } from '@/components/ui/input';
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||||
import { Textarea } from '@/components/ui/textarea';
|
import { Textarea } from '@/components/ui/textarea';
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
import { Checkbox } from '@/components/ui/checkbox';
|
||||||
|
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||||
|
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem } from '@/components/ui/command';
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
|
import { ChevronsUpDown, X } from 'lucide-react';
|
||||||
import { useToast } from '@/components/ui/use-toast';
|
import { useToast } from '@/components/ui/use-toast';
|
||||||
import type { FlowNode, FlowNodeData, FlowEdge } from '../types';
|
import type { FlowNode, FlowNodeData, FlowEdge } from '../types';
|
||||||
import type { WorkflowNodeDefinition, JSONSchema } from '../nodes/types';
|
import type { WorkflowNodeDefinition, JSONSchema } from '../nodes/types';
|
||||||
@ -28,6 +32,94 @@ interface NodeConfigModalProps {
|
|||||||
onOk: (nodeId: string, updatedData: Partial<FlowNodeData>) => void;
|
onOk: (nodeId: string, updatedData: Partial<FlowNodeData>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ 多选组件(使用 shadcn/ui)
|
||||||
|
interface MultiSelectProps {
|
||||||
|
options: Array<{ label: string; value: any }>;
|
||||||
|
value: any[];
|
||||||
|
onChange: (value: any[]) => void;
|
||||||
|
placeholder?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MultiSelect: React.FC<MultiSelectProps> = ({ options, value = [], onChange, placeholder, disabled }) => {
|
||||||
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
|
const handleSelect = (optionValue: any) => {
|
||||||
|
const newValues = value.includes(optionValue)
|
||||||
|
? value.filter((v: any) => v !== optionValue)
|
||||||
|
: [...value, optionValue];
|
||||||
|
onChange(newValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleRemove = (optionValue: any) => {
|
||||||
|
onChange(value.filter((v: any) => v !== optionValue));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
role="combobox"
|
||||||
|
aria-expanded={open}
|
||||||
|
className="w-full justify-between"
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
{value.length > 0
|
||||||
|
? `已选择 ${value.length} 项`
|
||||||
|
: placeholder || '请选择'}
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-[400px] p-0" align="start">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="搜索..." />
|
||||||
|
<CommandEmpty>未找到选项</CommandEmpty>
|
||||||
|
<CommandGroup className="max-h-64 overflow-auto">
|
||||||
|
{options.map((option) => (
|
||||||
|
<CommandItem
|
||||||
|
key={option.value}
|
||||||
|
value={option.value}
|
||||||
|
onSelect={() => handleSelect(option.value)}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
checked={value.includes(option.value)}
|
||||||
|
className="mr-2"
|
||||||
|
/>
|
||||||
|
{option.label}
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{/* 已选择的标签 */}
|
||||||
|
{value.length > 0 && (
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{value.map((val: any) => {
|
||||||
|
const option = options.find((opt: any) => opt.value === val);
|
||||||
|
return (
|
||||||
|
<Badge key={val} variant="secondary" className="px-2 py-1">
|
||||||
|
{option?.label || val}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="ml-1 hover:text-destructive"
|
||||||
|
onClick={() => handleRemove(val)}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
<X className="h-3 w-3" />
|
||||||
|
</button>
|
||||||
|
</Badge>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
||||||
visible,
|
visible,
|
||||||
node,
|
node,
|
||||||
@ -294,6 +386,56 @@ const NodeConfigModal: React.FC<NodeConfigModalProps> = ({
|
|||||||
// 动态数据源
|
// 动态数据源
|
||||||
if (prop['x-dataSource']) {
|
if (prop['x-dataSource']) {
|
||||||
const options = dataSourceCache[prop['x-dataSource']] || [];
|
const options = dataSourceCache[prop['x-dataSource']] || [];
|
||||||
|
|
||||||
|
// ✅ 数组类型 - 检查是否应该是多选
|
||||||
|
if (prop.type === 'array') {
|
||||||
|
// 检查 x-multiple-condition(是否应该多选)
|
||||||
|
let isMultiple = true; // 默认多选
|
||||||
|
|
||||||
|
if (prop['x-multiple-condition']) {
|
||||||
|
const multipleCondition = prop['x-multiple-condition'];
|
||||||
|
const conditionField = multipleCondition.field;
|
||||||
|
const conditionValue = multipleCondition.value;
|
||||||
|
const conditionOperator = multipleCondition.operator || '===';
|
||||||
|
|
||||||
|
// 获取条件字段的当前值
|
||||||
|
const currentFieldValue = inputForm.watch(conditionField);
|
||||||
|
|
||||||
|
// 评估条件
|
||||||
|
isMultiple = evaluateCondition(currentFieldValue, conditionValue, conditionOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是单选模式
|
||||||
|
if (!isMultiple) {
|
||||||
|
return renderSelect(
|
||||||
|
options,
|
||||||
|
{
|
||||||
|
...field,
|
||||||
|
// 转换数组为单个值
|
||||||
|
value: Array.isArray(field.value) && field.value.length > 0 ? field.value[0] : field.value,
|
||||||
|
onChange: (value: any) => {
|
||||||
|
// 单选时,将值包装为数组
|
||||||
|
field.onChange([value]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
prop,
|
||||||
|
loadingDataSources || loading
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多选模式
|
||||||
|
return (
|
||||||
|
<MultiSelect
|
||||||
|
options={options}
|
||||||
|
value={field.value || []}
|
||||||
|
onChange={field.onChange}
|
||||||
|
placeholder={prop.description || `请选择${prop.title || ''}`}
|
||||||
|
disabled={loadingDataSources || loading}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 单选类型
|
||||||
return renderSelect(
|
return renderSelect(
|
||||||
options,
|
options,
|
||||||
field,
|
field,
|
||||||
|
|||||||
@ -63,40 +63,55 @@ export const ApprovalNodeDefinition: ConfigurableNodeDefinition = {
|
|||||||
approvers: {
|
approvers: {
|
||||||
type: "array",
|
type: "array",
|
||||||
title: "审批人列表",
|
title: "审批人列表",
|
||||||
description: "选择具体的审批人。会签模式下:选中的所有用户都必须审批;或签模式下:任一用户审批即可",
|
description: "单人审批:选择一个审批人;会签模式:选中的所有用户都必须审批;或签模式:任一用户审批即可",
|
||||||
items: {
|
items: {
|
||||||
type: "number"
|
type: "string" // 后台使用 username(字符串)
|
||||||
},
|
},
|
||||||
'x-dataSource': DataSourceType.USERS,
|
'x-dataSource': DataSourceType.USERS,
|
||||||
'x-condition': {
|
'x-condition': {
|
||||||
field: 'approverType',
|
field: 'approverType',
|
||||||
value: 'USER'
|
value: 'USER'
|
||||||
|
},
|
||||||
|
'x-multiple-condition': {
|
||||||
|
field: 'approvalMode',
|
||||||
|
operator: 'in',
|
||||||
|
value: ['ALL', 'ANY'] // 只有会签和或签才是多选
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
approverRoles: {
|
approverRoles: {
|
||||||
type: "array",
|
type: "array",
|
||||||
title: "审批角色",
|
title: "审批角色",
|
||||||
description: "选择审批角色。会签模式下:拥有选中角色的所有用户都必须审批;或签模式下:任一拥有该角色的用户审批即可",
|
description: "单人审批:选择一个角色;会签模式:拥有选中角色的所有用户都必须审批;或签模式:任一拥有该角色的用户审批即可",
|
||||||
items: {
|
items: {
|
||||||
type: "number"
|
type: "string" // 使用 code(字符串)
|
||||||
},
|
},
|
||||||
'x-dataSource': DataSourceType.ROLES,
|
'x-dataSource': DataSourceType.ROLES,
|
||||||
'x-condition': {
|
'x-condition': {
|
||||||
field: 'approverType',
|
field: 'approverType',
|
||||||
value: 'ROLE'
|
value: 'ROLE'
|
||||||
|
},
|
||||||
|
'x-multiple-condition': {
|
||||||
|
field: 'approvalMode',
|
||||||
|
operator: 'in',
|
||||||
|
value: ['ALL', 'ANY']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
approverDepartments: {
|
approverDepartments: {
|
||||||
type: "array",
|
type: "array",
|
||||||
title: "审批部门",
|
title: "审批部门",
|
||||||
description: "选择审批部门。会签模式下:选中部门的所有成员都必须审批;或签模式下:任一部门成员审批即可",
|
description: "单人审批:选择一个部门;会签模式:选中部门的所有成员都必须审批;或签模式:任一部门成员审批即可",
|
||||||
items: {
|
items: {
|
||||||
type: "number"
|
type: "string" // 使用 code(字符串)
|
||||||
},
|
},
|
||||||
'x-dataSource': DataSourceType.DEPARTMENTS,
|
'x-dataSource': DataSourceType.DEPARTMENTS,
|
||||||
'x-condition': {
|
'x-condition': {
|
||||||
field: 'approverType',
|
field: 'approverType',
|
||||||
value: 'DEPARTMENT'
|
value: 'DEPARTMENT'
|
||||||
|
},
|
||||||
|
'x-multiple-condition': {
|
||||||
|
field: 'approvalMode',
|
||||||
|
operator: 'in',
|
||||||
|
value: ['ALL', 'ANY']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
approverVariable: {
|
approverVariable: {
|
||||||
|
|||||||
@ -18,6 +18,34 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
|
|
||||||
const config = definition.renderConfig;
|
const config = definition.renderConfig;
|
||||||
|
|
||||||
|
// 条件评估函数
|
||||||
|
const evaluateCondition = (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);
|
||||||
|
case 'in':
|
||||||
|
return Array.isArray(expectedValue) && expectedValue.includes(currentValue);
|
||||||
|
default:
|
||||||
|
return currentValue === expectedValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 渲染输入字段标签(来自 inputMappingSchema)
|
// 渲染输入字段标签(来自 inputMappingSchema)
|
||||||
const renderInputSection = () => {
|
const renderInputSection = () => {
|
||||||
if (!isConfigurableNode(definition) || !definition.inputMappingSchema) {
|
if (!isConfigurableNode(definition) || !definition.inputMappingSchema) {
|
||||||
@ -32,14 +60,30 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const allInputs = Object.keys(schema.properties).map(key => {
|
const allInputs = Object.keys(schema.properties)
|
||||||
|
.map(key => {
|
||||||
const fieldSchema = schema.properties![key];
|
const fieldSchema = schema.properties![key];
|
||||||
const fieldValue = inputMapping[key];
|
const fieldValue = inputMapping[key];
|
||||||
|
|
||||||
// 检查字段是否已填写(非空、非null、非undefined、非空字符串)
|
// ✅ 检查 x-condition(字段是否应该显示)
|
||||||
|
if (fieldSchema['x-condition']) {
|
||||||
|
const condition = fieldSchema['x-condition'];
|
||||||
|
const conditionField = condition.field;
|
||||||
|
const conditionValue = condition.value;
|
||||||
|
const conditionOperator = condition.operator || '===';
|
||||||
|
const currentFieldValue = inputMapping[conditionField];
|
||||||
|
|
||||||
|
// 如果条件不满足,跳过该字段
|
||||||
|
if (!evaluateCondition(currentFieldValue, conditionValue, conditionOperator)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查字段是否已填写(非空、非null、非undefined、非空字符串、非空数组)
|
||||||
const isFilled = fieldValue !== undefined &&
|
const isFilled = fieldValue !== undefined &&
|
||||||
fieldValue !== null &&
|
fieldValue !== null &&
|
||||||
fieldValue !== '' &&
|
fieldValue !== '' &&
|
||||||
|
!(Array.isArray(fieldValue) && fieldValue.length === 0) &&
|
||||||
(typeof fieldValue !== 'number' || !isNaN(fieldValue));
|
(typeof fieldValue !== 'number' || !isNaN(fieldValue));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -48,7 +92,8 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
description: fieldSchema.description,
|
description: fieldSchema.description,
|
||||||
isFilled,
|
isFilled,
|
||||||
};
|
};
|
||||||
});
|
})
|
||||||
|
.filter((input): input is NonNullable<typeof input> => input !== null); // 过滤掉条件不满足的字段
|
||||||
|
|
||||||
if (allInputs.length === 0) {
|
if (allInputs.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -102,35 +102,37 @@ export const DATA_SOURCE_REGISTRY: Record<DataSourceType, DataSourceConfig> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[DataSourceType.USERS]: {
|
[DataSourceType.USERS]: {
|
||||||
url: '/api/v1/system/users/page',
|
url: '/api/v1/user/list',
|
||||||
params: {pageSize: 1000},
|
transform: (data: any[]) => {
|
||||||
transform: (data: any) => {
|
return data.map((item: any) => ({
|
||||||
const users = data.content || data;
|
label: `${item.nickname} (${item.username})`,
|
||||||
return users.map((item: any) => ({
|
value: item.username, // 后台使用 username 进行审批
|
||||||
label: `${item.name} (${item.username})`,
|
id: item.id,
|
||||||
value: item.id,
|
email: item.email,
|
||||||
username: item.username,
|
departmentName: item.departmentName
|
||||||
email: item.email
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[DataSourceType.ROLES]: {
|
[DataSourceType.ROLES]: {
|
||||||
url: '/api/v1/system/roles/list',
|
url: '/api/v1/role/list',
|
||||||
transform: (data: any[]) => {
|
transform: (data: any[]) => {
|
||||||
return data.map((item: any) => ({
|
return data.map((item: any) => ({
|
||||||
label: item.name,
|
label: `${item.name} (${item.code})`,
|
||||||
value: item.id,
|
value: item.code, // 使用 code 作为值
|
||||||
code: item.code
|
id: item.id,
|
||||||
|
description: item.description
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[DataSourceType.DEPARTMENTS]: {
|
[DataSourceType.DEPARTMENTS]: {
|
||||||
url: '/api/v1/system/departments/list',
|
url: '/api/v1/department/list',
|
||||||
transform: (data: any[]) => {
|
transform: (data: any[]) => {
|
||||||
return data.map((item: any) => ({
|
return data.map((item: any) => ({
|
||||||
label: item.name,
|
label: `${item.name} (${item.code})`,
|
||||||
value: item.id,
|
value: item.code, // 使用 code 作为值
|
||||||
code: item.code
|
id: item.id,
|
||||||
|
description: item.description,
|
||||||
|
parentId: item.parentId
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user