1
20 小时以前 54de9faad9bf00e13b23f024e94bf486a9b3c959
lsh#
108个文件已添加
11068 ■■■■■ 已修改文件
rsf-admin/src/page/flowInstance/FlowInstanceCreate.jsx 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowInstance/FlowInstanceEdit.jsx 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowInstance/FlowInstanceList.jsx 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowInstance/FlowInstancePanel.jsx 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowInstance/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepInstance/FlowStepInstanceCreate.jsx 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepInstance/FlowStepInstanceEdit.jsx 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepInstance/FlowStepInstanceList.jsx 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepInstance/FlowStepInstancePanel.jsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepInstance/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepLog/FlowStepLogCreate.jsx 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepLog/FlowStepLogEdit.jsx 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepLog/FlowStepLogList.jsx 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepLog/FlowStepLogPanel.jsx 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepLog/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateCreate.jsx 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateEdit.jsx 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateList.jsx 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepTemplate/FlowStepTemplatePanel.jsx 141 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowStepTemplate/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateCreate.jsx 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateEdit.jsx 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateList.jsx 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplatePanel.jsx 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/subsystemFlowTemplate/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstance/TaskInstanceCreate.jsx 321 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstance/TaskInstanceEdit.jsx 293 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstance/TaskInstanceList.jsx 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstance/TaskInstancePanel.jsx 231 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstance/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeCreate.jsx 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeEdit.jsx 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeList.jsx 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodePanel.jsx 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskInstanceNode/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateCreate.jsx 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateEdit.jsx 216 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateList.jsx 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplate/TaskPathTemplatePanel.jsx 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplate/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeCreate.jsx 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeEdit.jsx 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeList.jsx 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodePanel.jsx 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/taskPathTemplateNode/index.jsx 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowInstanceController.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepInstanceController.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepLogController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepTemplateController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/SubsystemFlowTemplateController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskInstanceController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskInstanceNodeController.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskPathTemplateController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskPathTemplateNodeController.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowInstance.java 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepInstance.java 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepLog.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepTemplate.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SubsystemFlowTemplate.java 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskInstance.java 379 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskInstanceNode.java 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskPathTemplate.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskPathTemplateNode.java 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowInstanceMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepInstanceMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepLogMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepTemplateMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/SubsystemFlowTemplateMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskInstanceMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskInstanceNodeMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskPathTemplateMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskPathTemplateNodeMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowInstanceService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepInstanceService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepLogService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepTemplateService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/SubsystemFlowTemplateService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskInstanceNodeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskInstanceService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskPathTemplateNodeService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskPathTemplateService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowInstanceServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepInstanceServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepLogServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepTemplateServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/SubsystemFlowTemplateServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskInstanceNodeServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskInstanceServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskPathTemplateNodeServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskPathTemplateServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/flowInstance.sql 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/flowStepInstance.sql 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/flowStepLog.sql 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/flowStepTemplate.sql 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/subsystemFlowTemplate.sql 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/taskInstance.sql 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/taskInstanceNode.sql 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/taskPathTemplate.sql 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/java/taskPathTemplateNode.sql 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/FlowInstanceMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/FlowStepInstanceMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/FlowStepLogMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/FlowStepTemplateMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/SubsystemFlowTemplateMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/TaskInstanceMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/TaskInstanceNodeMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/TaskPathTemplateMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-server/src/main/resources/mapper/system/TaskPathTemplateNodeMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsf-admin/src/page/flowInstance/FlowInstanceCreate.jsx
New file
@@ -0,0 +1,256 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const FlowInstanceCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.flowInstanceNo"
                                        source="flowInstanceNo"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.taskId"
                                        source="taskId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.taskNo"
                                        source="taskNo"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.nodeInstanceId"
                                        source="nodeInstanceId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.nodeCode"
                                        source="nodeCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.flowTemplateId"
                                        source="flowTemplateId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.flowTemplateCode"
                                        source="flowTemplateCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.templateVersion"
                                        source="templateVersion"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.currentStepCode"
                                        source="currentStepCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.currentStepOrder"
                                        source="currentStepOrder"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.executeParams"
                                        source="executeParams"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.executeResult"
                                        source="executeResult"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.errorCode"
                                        source="errorCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.errorMessage"
                                        source="errorMessage"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowInstance.startTime"
                                        source="startTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowInstance.endTime"
                                        source="endTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowInstance.timeoutAt"
                                        source="timeoutAt"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.durationSeconds"
                                        source="durationSeconds"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowInstance.retryTimes"
                                        source="retryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowInstance.lastRetryTime"
                                        source="lastRetryTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowInstance.contextData"
                                        source="contextData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default FlowInstanceCreate;
rsf-admin/src/page/flowInstance/FlowInstanceEdit.jsx
New file
@@ -0,0 +1,228 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const FlowInstanceEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.flowInstanceNo"
                                source="flowInstanceNo"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.taskId"
                                source="taskId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.taskNo"
                                source="taskNo"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.nodeInstanceId"
                                source="nodeInstanceId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.nodeCode"
                                source="nodeCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.flowTemplateId"
                                source="flowTemplateId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.flowTemplateCode"
                                source="flowTemplateCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.templateVersion"
                                source="templateVersion"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.currentStepCode"
                                source="currentStepCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.currentStepOrder"
                                source="currentStepOrder"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.executeParams"
                                source="executeParams"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.executeResult"
                                source="executeResult"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.errorCode"
                                source="errorCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.errorMessage"
                                source="errorMessage"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowInstance.startTime"
                                source="startTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowInstance.endTime"
                                source="endTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowInstance.timeoutAt"
                                source="timeoutAt"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.durationSeconds"
                                source="durationSeconds"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowInstance.retryTimes"
                                source="retryTimes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowInstance.lastRetryTime"
                                source="lastRetryTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowInstance.contextData"
                                source="contextData"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default FlowInstanceEdit;
rsf-admin/src/page/flowInstance/FlowInstanceList.jsx
New file
@@ -0,0 +1,192 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import FlowInstanceCreate from "./FlowInstanceCreate";
import FlowInstancePanel from "./FlowInstancePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="flowInstanceNo" label="table.field.flowInstance.flowInstanceNo" />,
    <NumberInput source="taskId" label="table.field.flowInstance.taskId" />,
    <TextInput source="taskNo" label="table.field.flowInstance.taskNo" />,
    <NumberInput source="nodeInstanceId" label="table.field.flowInstance.nodeInstanceId" />,
    <TextInput source="nodeCode" label="table.field.flowInstance.nodeCode" />,
    <NumberInput source="flowTemplateId" label="table.field.flowInstance.flowTemplateId" />,
    <TextInput source="flowTemplateCode" label="table.field.flowInstance.flowTemplateCode" />,
    <NumberInput source="templateVersion" label="table.field.flowInstance.templateVersion" />,
    <TextInput source="currentStepCode" label="table.field.flowInstance.currentStepCode" />,
    <NumberInput source="currentStepOrder" label="table.field.flowInstance.currentStepOrder" />,
    <TextInput source="executeParams" label="table.field.flowInstance.executeParams" />,
    <TextInput source="executeResult" label="table.field.flowInstance.executeResult" />,
    <TextInput source="errorCode" label="table.field.flowInstance.errorCode" />,
    <TextInput source="errorMessage" label="table.field.flowInstance.errorMessage" />,
    <DateInput source="startTime" label="table.field.flowInstance.startTime" />,
    <DateInput source="endTime" label="table.field.flowInstance.endTime" />,
    <DateInput source="timeoutAt" label="table.field.flowInstance.timeoutAt" />,
    <NumberInput source="durationSeconds" label="table.field.flowInstance.durationSeconds" />,
    <NumberInput source="retryTimes" label="table.field.flowInstance.retryTimes" />,
    <DateInput source="lastRetryTime" label="table.field.flowInstance.lastRetryTime" />,
    <TextInput source="contextData" label="table.field.flowInstance.contextData" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const FlowInstanceList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.flowInstance"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='flowInstance' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='flowInstance'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <FlowInstancePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="flowInstanceNo" label="table.field.flowInstance.flowInstanceNo" />
                    <NumberField source="taskId" label="table.field.flowInstance.taskId" />
                    <TextField source="taskNo" label="table.field.flowInstance.taskNo" />
                    <NumberField source="nodeInstanceId" label="table.field.flowInstance.nodeInstanceId" />
                    <TextField source="nodeCode" label="table.field.flowInstance.nodeCode" />
                    <NumberField source="flowTemplateId" label="table.field.flowInstance.flowTemplateId" />
                    <TextField source="flowTemplateCode" label="table.field.flowInstance.flowTemplateCode" />
                    <NumberField source="templateVersion" label="table.field.flowInstance.templateVersion" />
                    <TextField source="currentStepCode" label="table.field.flowInstance.currentStepCode" />
                    <NumberField source="currentStepOrder" label="table.field.flowInstance.currentStepOrder" />
                    <TextField source="executeParams" label="table.field.flowInstance.executeParams" />
                    <TextField source="executeResult" label="table.field.flowInstance.executeResult" />
                    <TextField source="errorCode" label="table.field.flowInstance.errorCode" />
                    <TextField source="errorMessage" label="table.field.flowInstance.errorMessage" />
                    <DateField source="startTime" label="table.field.flowInstance.startTime" showTime />
                    <DateField source="endTime" label="table.field.flowInstance.endTime" showTime />
                    <DateField source="timeoutAt" label="table.field.flowInstance.timeoutAt" showTime />
                    <NumberField source="durationSeconds" label="table.field.flowInstance.durationSeconds" />
                    <NumberField source="retryTimes" label="table.field.flowInstance.retryTimes" />
                    <DateField source="lastRetryTime" label="table.field.flowInstance.lastRetryTime" showTime />
                    <TextField source="contextData" label="table.field.flowInstance.contextData" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <FlowInstanceCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='FlowInstance Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default FlowInstanceList;
rsf-admin/src/page/flowInstance/FlowInstancePanel.jsx
New file
@@ -0,0 +1,177 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const FlowInstancePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.flowInstance.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.flowInstanceNo"
                                property={record.flowInstanceNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.taskId"
                                property={record.taskId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.taskNo"
                                property={record.taskNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.nodeInstanceId"
                                property={record.nodeInstanceId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.nodeCode"
                                property={record.nodeCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.flowTemplateId"
                                property={record.flowTemplateId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.flowTemplateCode"
                                property={record.flowTemplateCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.templateVersion"
                                property={record.templateVersion}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.currentStepCode"
                                property={record.currentStepCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.currentStepOrder"
                                property={record.currentStepOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.executeParams"
                                property={record.executeParams}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.executeResult"
                                property={record.executeResult}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.errorCode"
                                property={record.errorCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.errorMessage"
                                property={record.errorMessage}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.startTime"
                                property={record.startTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.endTime"
                                property={record.endTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.timeoutAt"
                                property={record.timeoutAt$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.durationSeconds"
                                property={record.durationSeconds}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.retryTimes"
                                property={record.retryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.lastRetryTime"
                                property={record.lastRetryTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowInstance.contextData"
                                property={record.contextData}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default FlowInstancePanel;
rsf-admin/src/page/flowInstance/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import FlowInstanceList from "./FlowInstanceList";
import FlowInstanceEdit from "./FlowInstanceEdit";
export default {
    list: FlowInstanceList,
    edit: FlowInstanceEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/flowStepInstance/FlowStepInstanceCreate.jsx
New file
@@ -0,0 +1,224 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const FlowStepInstanceCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepInstance.flowInstanceId"
                                        source="flowInstanceId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.flowInstanceNo"
                                        source="flowInstanceNo"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepInstance.stepOrder"
                                        source="stepOrder"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.stepCode"
                                        source="stepCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.stepName"
                                        source="stepName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.stepType"
                                        source="stepType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepInstance.stepTemplateId"
                                        source="stepTemplateId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.executeResult"
                                        source="executeResult"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.errorCode"
                                        source="errorCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.errorMessage"
                                        source="errorMessage"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowStepInstance.startTime"
                                        source="startTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.flowStepInstance.endTime"
                                        source="endTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepInstance.durationSeconds"
                                        source="durationSeconds"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.inputData"
                                        source="inputData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepInstance.outputData"
                                        source="outputData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepInstance.retryTimes"
                                        source="retryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default FlowStepInstanceCreate;
rsf-admin/src/page/flowStepInstance/FlowStepInstanceEdit.jsx
New file
@@ -0,0 +1,196 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const FlowStepInstanceEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepInstance.flowInstanceId"
                                source="flowInstanceId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.flowInstanceNo"
                                source="flowInstanceNo"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepInstance.stepOrder"
                                source="stepOrder"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.stepCode"
                                source="stepCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.stepName"
                                source="stepName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.stepType"
                                source="stepType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepInstance.stepTemplateId"
                                source="stepTemplateId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.executeResult"
                                source="executeResult"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.errorCode"
                                source="errorCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.errorMessage"
                                source="errorMessage"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowStepInstance.startTime"
                                source="startTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.flowStepInstance.endTime"
                                source="endTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepInstance.durationSeconds"
                                source="durationSeconds"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.inputData"
                                source="inputData"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepInstance.outputData"
                                source="outputData"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepInstance.retryTimes"
                                source="retryTimes"
                                validate={required()}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default FlowStepInstanceEdit;
rsf-admin/src/page/flowStepInstance/FlowStepInstanceList.jsx
New file
@@ -0,0 +1,182 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import FlowStepInstanceCreate from "./FlowStepInstanceCreate";
import FlowStepInstancePanel from "./FlowStepInstancePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="flowInstanceId" label="table.field.flowStepInstance.flowInstanceId" />,
    <TextInput source="flowInstanceNo" label="table.field.flowStepInstance.flowInstanceNo" />,
    <NumberInput source="stepOrder" label="table.field.flowStepInstance.stepOrder" />,
    <TextInput source="stepCode" label="table.field.flowStepInstance.stepCode" />,
    <TextInput source="stepName" label="table.field.flowStepInstance.stepName" />,
    <TextInput source="stepType" label="table.field.flowStepInstance.stepType" />,
    <NumberInput source="stepTemplateId" label="table.field.flowStepInstance.stepTemplateId" />,
    <TextInput source="executeResult" label="table.field.flowStepInstance.executeResult" />,
    <TextInput source="errorCode" label="table.field.flowStepInstance.errorCode" />,
    <TextInput source="errorMessage" label="table.field.flowStepInstance.errorMessage" />,
    <DateInput source="startTime" label="table.field.flowStepInstance.startTime" />,
    <DateInput source="endTime" label="table.field.flowStepInstance.endTime" />,
    <NumberInput source="durationSeconds" label="table.field.flowStepInstance.durationSeconds" />,
    <TextInput source="inputData" label="table.field.flowStepInstance.inputData" />,
    <TextInput source="outputData" label="table.field.flowStepInstance.outputData" />,
    <NumberInput source="retryTimes" label="table.field.flowStepInstance.retryTimes" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const FlowStepInstanceList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.flowStepInstance"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='flowStepInstance' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='flowStepInstance'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <FlowStepInstancePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="flowInstanceId" label="table.field.flowStepInstance.flowInstanceId" />
                    <TextField source="flowInstanceNo" label="table.field.flowStepInstance.flowInstanceNo" />
                    <NumberField source="stepOrder" label="table.field.flowStepInstance.stepOrder" />
                    <TextField source="stepCode" label="table.field.flowStepInstance.stepCode" />
                    <TextField source="stepName" label="table.field.flowStepInstance.stepName" />
                    <TextField source="stepType" label="table.field.flowStepInstance.stepType" />
                    <NumberField source="stepTemplateId" label="table.field.flowStepInstance.stepTemplateId" />
                    <TextField source="executeResult" label="table.field.flowStepInstance.executeResult" />
                    <TextField source="errorCode" label="table.field.flowStepInstance.errorCode" />
                    <TextField source="errorMessage" label="table.field.flowStepInstance.errorMessage" />
                    <DateField source="startTime" label="table.field.flowStepInstance.startTime" showTime />
                    <DateField source="endTime" label="table.field.flowStepInstance.endTime" showTime />
                    <NumberField source="durationSeconds" label="table.field.flowStepInstance.durationSeconds" />
                    <TextField source="inputData" label="table.field.flowStepInstance.inputData" />
                    <TextField source="outputData" label="table.field.flowStepInstance.outputData" />
                    <NumberField source="retryTimes" label="table.field.flowStepInstance.retryTimes" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <FlowStepInstanceCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='FlowStepInstance Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default FlowStepInstanceList;
rsf-admin/src/page/flowStepInstance/FlowStepInstancePanel.jsx
New file
@@ -0,0 +1,147 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const FlowStepInstancePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.flowStepInstance.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.flowInstanceId"
                                property={record.flowInstanceId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.flowInstanceNo"
                                property={record.flowInstanceNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.stepOrder"
                                property={record.stepOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.stepCode"
                                property={record.stepCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.stepName"
                                property={record.stepName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.stepType"
                                property={record.stepType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.stepTemplateId"
                                property={record.stepTemplateId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.executeResult"
                                property={record.executeResult}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.errorCode"
                                property={record.errorCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.errorMessage"
                                property={record.errorMessage}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.startTime"
                                property={record.startTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.endTime"
                                property={record.endTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.durationSeconds"
                                property={record.durationSeconds}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.inputData"
                                property={record.inputData}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.outputData"
                                property={record.outputData}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepInstance.retryTimes"
                                property={record.retryTimes}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default FlowStepInstancePanel;
rsf-admin/src/page/flowStepInstance/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import FlowStepInstanceList from "./FlowStepInstanceList";
import FlowStepInstanceEdit from "./FlowStepInstanceEdit";
export default {
    list: FlowStepInstanceList,
    edit: FlowStepInstanceEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/flowStepLog/FlowStepLogCreate.jsx
New file
@@ -0,0 +1,162 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const FlowStepLogCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepLog.flowInstanceId"
                                        source="flowInstanceId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepLog.stepInstanceId"
                                        source="stepInstanceId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepLog.logType"
                                        source="logType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepLog.logLevel"
                                        source="logLevel"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepLog.logContent"
                                        source="logContent"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepLog.requestData"
                                        source="requestData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepLog.responseData"
                                        source="responseData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default FlowStepLogCreate;
rsf-admin/src/page/flowStepLog/FlowStepLogEdit.jsx
New file
@@ -0,0 +1,134 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const FlowStepLogEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepLog.flowInstanceId"
                                source="flowInstanceId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepLog.stepInstanceId"
                                source="stepInstanceId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepLog.logType"
                                source="logType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepLog.logLevel"
                                source="logLevel"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepLog.logContent"
                                source="logContent"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepLog.requestData"
                                source="requestData"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepLog.responseData"
                                source="responseData"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default FlowStepLogEdit;
rsf-admin/src/page/flowStepLog/FlowStepLogList.jsx
New file
@@ -0,0 +1,164 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import FlowStepLogCreate from "./FlowStepLogCreate";
import FlowStepLogPanel from "./FlowStepLogPanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="flowInstanceId" label="table.field.flowStepLog.flowInstanceId" />,
    <NumberInput source="stepInstanceId" label="table.field.flowStepLog.stepInstanceId" />,
    <TextInput source="logType" label="table.field.flowStepLog.logType" />,
    <TextInput source="logLevel" label="table.field.flowStepLog.logLevel" />,
    <TextInput source="logContent" label="table.field.flowStepLog.logContent" />,
    <TextInput source="requestData" label="table.field.flowStepLog.requestData" />,
    <TextInput source="responseData" label="table.field.flowStepLog.responseData" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const FlowStepLogList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.flowStepLog"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='flowStepLog' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='flowStepLog'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <FlowStepLogPanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="flowInstanceId" label="table.field.flowStepLog.flowInstanceId" />
                    <NumberField source="stepInstanceId" label="table.field.flowStepLog.stepInstanceId" />
                    <TextField source="logType" label="table.field.flowStepLog.logType" />
                    <TextField source="logLevel" label="table.field.flowStepLog.logLevel" />
                    <TextField source="logContent" label="table.field.flowStepLog.logContent" />
                    <TextField source="requestData" label="table.field.flowStepLog.requestData" />
                    <TextField source="responseData" label="table.field.flowStepLog.responseData" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <FlowStepLogCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='FlowStepLog Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default FlowStepLogList;
rsf-admin/src/page/flowStepLog/FlowStepLogPanel.jsx
New file
@@ -0,0 +1,93 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const FlowStepLogPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.flowStepLog.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.flowInstanceId"
                                property={record.flowInstanceId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.stepInstanceId"
                                property={record.stepInstanceId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.logType"
                                property={record.logType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.logLevel"
                                property={record.logLevel}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.logContent"
                                property={record.logContent}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.requestData"
                                property={record.requestData}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepLog.responseData"
                                property={record.responseData}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default FlowStepLogPanel;
rsf-admin/src/page/flowStepLog/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import FlowStepLogList from "./FlowStepLogList";
import FlowStepLogEdit from "./FlowStepLogEdit";
export default {
    list: FlowStepLogList,
    edit: FlowStepLogEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateCreate.jsx
New file
@@ -0,0 +1,219 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const FlowStepTemplateCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepTemplate.flowId"
                                        source="flowId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.flowCode"
                                        source="flowCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepTemplate.stepOrder"
                                        source="stepOrder"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.stepCode"
                                        source="stepCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.stepName"
                                        source="stepName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.stepType"
                                        source="stepType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.actionType"
                                        source="actionType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.actionConfig"
                                        source="actionConfig"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.inputMapping"
                                        source="inputMapping"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.outputMapping"
                                        source="outputMapping"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.conditionExpression"
                                        source="conditionExpression"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepTemplate.skipOnFail"
                                        source="skipOnFail"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepTemplate.retryEnabled"
                                        source="retryEnabled"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.flowStepTemplate.retryConfig"
                                        source="retryConfig"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.flowStepTemplate.timeoutSeconds"
                                        source="timeoutSeconds"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default FlowStepTemplateCreate;
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateEdit.jsx
New file
@@ -0,0 +1,191 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const FlowStepTemplateEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepTemplate.flowId"
                                source="flowId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.flowCode"
                                source="flowCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepTemplate.stepOrder"
                                source="stepOrder"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.stepCode"
                                source="stepCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.stepName"
                                source="stepName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.stepType"
                                source="stepType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.actionType"
                                source="actionType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.actionConfig"
                                source="actionConfig"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.inputMapping"
                                source="inputMapping"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.outputMapping"
                                source="outputMapping"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.conditionExpression"
                                source="conditionExpression"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepTemplate.skipOnFail"
                                source="skipOnFail"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepTemplate.retryEnabled"
                                source="retryEnabled"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.flowStepTemplate.retryConfig"
                                source="retryConfig"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.flowStepTemplate.timeoutSeconds"
                                source="timeoutSeconds"
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default FlowStepTemplateEdit;
rsf-admin/src/page/flowStepTemplate/FlowStepTemplateList.jsx
New file
@@ -0,0 +1,180 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import FlowStepTemplateCreate from "./FlowStepTemplateCreate";
import FlowStepTemplatePanel from "./FlowStepTemplatePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="flowId" label="table.field.flowStepTemplate.flowId" />,
    <TextInput source="flowCode" label="table.field.flowStepTemplate.flowCode" />,
    <NumberInput source="stepOrder" label="table.field.flowStepTemplate.stepOrder" />,
    <TextInput source="stepCode" label="table.field.flowStepTemplate.stepCode" />,
    <TextInput source="stepName" label="table.field.flowStepTemplate.stepName" />,
    <TextInput source="stepType" label="table.field.flowStepTemplate.stepType" />,
    <TextInput source="actionType" label="table.field.flowStepTemplate.actionType" />,
    <TextInput source="actionConfig" label="table.field.flowStepTemplate.actionConfig" />,
    <TextInput source="inputMapping" label="table.field.flowStepTemplate.inputMapping" />,
    <TextInput source="outputMapping" label="table.field.flowStepTemplate.outputMapping" />,
    <TextInput source="conditionExpression" label="table.field.flowStepTemplate.conditionExpression" />,
    <NumberInput source="skipOnFail" label="table.field.flowStepTemplate.skipOnFail" />,
    <NumberInput source="retryEnabled" label="table.field.flowStepTemplate.retryEnabled" />,
    <TextInput source="retryConfig" label="table.field.flowStepTemplate.retryConfig" />,
    <NumberInput source="timeoutSeconds" label="table.field.flowStepTemplate.timeoutSeconds" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const FlowStepTemplateList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.flowStepTemplate"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='flowStepTemplate' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='flowStepTemplate'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <FlowStepTemplatePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="flowId" label="table.field.flowStepTemplate.flowId" />
                    <TextField source="flowCode" label="table.field.flowStepTemplate.flowCode" />
                    <NumberField source="stepOrder" label="table.field.flowStepTemplate.stepOrder" />
                    <TextField source="stepCode" label="table.field.flowStepTemplate.stepCode" />
                    <TextField source="stepName" label="table.field.flowStepTemplate.stepName" />
                    <TextField source="stepType" label="table.field.flowStepTemplate.stepType" />
                    <TextField source="actionType" label="table.field.flowStepTemplate.actionType" />
                    <TextField source="actionConfig" label="table.field.flowStepTemplate.actionConfig" />
                    <TextField source="inputMapping" label="table.field.flowStepTemplate.inputMapping" />
                    <TextField source="outputMapping" label="table.field.flowStepTemplate.outputMapping" />
                    <TextField source="conditionExpression" label="table.field.flowStepTemplate.conditionExpression" />
                    <NumberField source="skipOnFail" label="table.field.flowStepTemplate.skipOnFail" />
                    <NumberField source="retryEnabled" label="table.field.flowStepTemplate.retryEnabled" />
                    <TextField source="retryConfig" label="table.field.flowStepTemplate.retryConfig" />
                    <NumberField source="timeoutSeconds" label="table.field.flowStepTemplate.timeoutSeconds" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <FlowStepTemplateCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='FlowStepTemplate Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default FlowStepTemplateList;
rsf-admin/src/page/flowStepTemplate/FlowStepTemplatePanel.jsx
New file
@@ -0,0 +1,141 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const FlowStepTemplatePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.flowStepTemplate.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.flowId"
                                property={record.flowId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.flowCode"
                                property={record.flowCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.stepOrder"
                                property={record.stepOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.stepCode"
                                property={record.stepCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.stepName"
                                property={record.stepName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.stepType"
                                property={record.stepType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.actionType"
                                property={record.actionType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.actionConfig"
                                property={record.actionConfig}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.inputMapping"
                                property={record.inputMapping}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.outputMapping"
                                property={record.outputMapping}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.conditionExpression"
                                property={record.conditionExpression}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.skipOnFail"
                                property={record.skipOnFail}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.retryEnabled"
                                property={record.retryEnabled}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.retryConfig"
                                property={record.retryConfig}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.flowStepTemplate.timeoutSeconds"
                                property={record.timeoutSeconds}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default FlowStepTemplatePanel;
rsf-admin/src/page/flowStepTemplate/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import FlowStepTemplateList from "./FlowStepTemplateList";
import FlowStepTemplateEdit from "./FlowStepTemplateEdit";
export default {
    list: FlowStepTemplateList,
    edit: FlowStepTemplateEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateCreate.jsx
New file
@@ -0,0 +1,210 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const SubsystemFlowTemplateCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.flowCode"
                                        source="flowCode"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.flowName"
                                        source="flowName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.systemCode"
                                        source="systemCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.systemName"
                                        source="systemName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.nodeType"
                                        source="nodeType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.subsystemFlowTemplate.version"
                                        source="version"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.subsystemFlowTemplate.isCurrent"
                                        source="isCurrent"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.subsystemFlowTemplate.effectiveTime"
                                        source="effectiveTime"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.timeoutStrategy"
                                        source="timeoutStrategy"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.subsystemFlowTemplate.timeoutSeconds"
                                        source="timeoutSeconds"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.subsystemFlowTemplate.maxRetryTimes"
                                        source="maxRetryTimes"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.subsystemFlowTemplate.needNotify"
                                        source="needNotify"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.notifyTemplate"
                                        source="notifyTemplate"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.subsystemFlowTemplate.remark"
                                        source="remark"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default SubsystemFlowTemplateCreate;
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateEdit.jsx
New file
@@ -0,0 +1,182 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const SubsystemFlowTemplateEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.flowCode"
                                source="flowCode"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.flowName"
                                source="flowName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.systemCode"
                                source="systemCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.systemName"
                                source="systemName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.nodeType"
                                source="nodeType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.subsystemFlowTemplate.version"
                                source="version"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.subsystemFlowTemplate.isCurrent"
                                source="isCurrent"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.subsystemFlowTemplate.effectiveTime"
                                source="effectiveTime"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.timeoutStrategy"
                                source="timeoutStrategy"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.subsystemFlowTemplate.timeoutSeconds"
                                source="timeoutSeconds"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.subsystemFlowTemplate.maxRetryTimes"
                                source="maxRetryTimes"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.subsystemFlowTemplate.needNotify"
                                source="needNotify"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.notifyTemplate"
                                source="notifyTemplate"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.subsystemFlowTemplate.remark"
                                source="remark"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default SubsystemFlowTemplateEdit;
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplateList.jsx
New file
@@ -0,0 +1,178 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import SubsystemFlowTemplateCreate from "./SubsystemFlowTemplateCreate";
import SubsystemFlowTemplatePanel from "./SubsystemFlowTemplatePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="flowCode" label="table.field.subsystemFlowTemplate.flowCode" />,
    <TextInput source="flowName" label="table.field.subsystemFlowTemplate.flowName" />,
    <TextInput source="systemCode" label="table.field.subsystemFlowTemplate.systemCode" />,
    <TextInput source="systemName" label="table.field.subsystemFlowTemplate.systemName" />,
    <TextInput source="nodeType" label="table.field.subsystemFlowTemplate.nodeType" />,
    <NumberInput source="version" label="table.field.subsystemFlowTemplate.version" />,
    <NumberInput source="isCurrent" label="table.field.subsystemFlowTemplate.isCurrent" />,
    <DateInput source="effectiveTime" label="table.field.subsystemFlowTemplate.effectiveTime" />,
    <TextInput source="timeoutStrategy" label="table.field.subsystemFlowTemplate.timeoutStrategy" />,
    <NumberInput source="timeoutSeconds" label="table.field.subsystemFlowTemplate.timeoutSeconds" />,
    <NumberInput source="maxRetryTimes" label="table.field.subsystemFlowTemplate.maxRetryTimes" />,
    <NumberInput source="needNotify" label="table.field.subsystemFlowTemplate.needNotify" />,
    <TextInput source="notifyTemplate" label="table.field.subsystemFlowTemplate.notifyTemplate" />,
    <TextInput source="remark" label="table.field.subsystemFlowTemplate.remark" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const SubsystemFlowTemplateList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.subsystemFlowTemplate"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='subsystemFlowTemplate' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='subsystemFlowTemplate'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <SubsystemFlowTemplatePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="flowCode" label="table.field.subsystemFlowTemplate.flowCode" />
                    <TextField source="flowName" label="table.field.subsystemFlowTemplate.flowName" />
                    <TextField source="systemCode" label="table.field.subsystemFlowTemplate.systemCode" />
                    <TextField source="systemName" label="table.field.subsystemFlowTemplate.systemName" />
                    <TextField source="nodeType" label="table.field.subsystemFlowTemplate.nodeType" />
                    <NumberField source="version" label="table.field.subsystemFlowTemplate.version" />
                    <NumberField source="isCurrent" label="table.field.subsystemFlowTemplate.isCurrent" />
                    <DateField source="effectiveTime" label="table.field.subsystemFlowTemplate.effectiveTime" showTime />
                    <TextField source="timeoutStrategy" label="table.field.subsystemFlowTemplate.timeoutStrategy" />
                    <NumberField source="timeoutSeconds" label="table.field.subsystemFlowTemplate.timeoutSeconds" />
                    <NumberField source="maxRetryTimes" label="table.field.subsystemFlowTemplate.maxRetryTimes" />
                    <NumberField source="needNotify" label="table.field.subsystemFlowTemplate.needNotify" />
                    <TextField source="notifyTemplate" label="table.field.subsystemFlowTemplate.notifyTemplate" />
                    <TextField source="remark" label="table.field.subsystemFlowTemplate.remark" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <SubsystemFlowTemplateCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='SubsystemFlowTemplate Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default SubsystemFlowTemplateList;
rsf-admin/src/page/subsystemFlowTemplate/SubsystemFlowTemplatePanel.jsx
New file
@@ -0,0 +1,135 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const SubsystemFlowTemplatePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.subsystemFlowTemplate.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.flowCode"
                                property={record.flowCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.flowName"
                                property={record.flowName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.systemCode"
                                property={record.systemCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.systemName"
                                property={record.systemName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.nodeType"
                                property={record.nodeType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.version"
                                property={record.version}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.isCurrent"
                                property={record.isCurrent}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.effectiveTime"
                                property={record.effectiveTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.timeoutStrategy"
                                property={record.timeoutStrategy}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.timeoutSeconds"
                                property={record.timeoutSeconds}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.maxRetryTimes"
                                property={record.maxRetryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.needNotify"
                                property={record.needNotify}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.notifyTemplate"
                                property={record.notifyTemplate}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.subsystemFlowTemplate.remark"
                                property={record.remark}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default SubsystemFlowTemplatePanel;
rsf-admin/src/page/subsystemFlowTemplate/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import SubsystemFlowTemplateList from "./SubsystemFlowTemplateList";
import SubsystemFlowTemplateEdit from "./SubsystemFlowTemplateEdit";
export default {
    list: SubsystemFlowTemplateList,
    edit: SubsystemFlowTemplateEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/taskInstance/TaskInstanceCreate.jsx
New file
@@ -0,0 +1,321 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const TaskInstanceCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.taskNo"
                                        source="taskNo"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.bizNo"
                                        source="bizNo"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.bizType"
                                        source="bizType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.templateId"
                                        source="templateId"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.templateCode"
                                        source="templateCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.templateVersion"
                                        source="templateVersion"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.sourceInfo"
                                        source="sourceInfo"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.targetInfo"
                                        source="targetInfo"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.sourceCode"
                                        source="sourceCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.targetCode"
                                        source="targetCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.plannedPath"
                                        source="plannedPath"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.actualPath"
                                        source="actualPath"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.priority"
                                        source="priority"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstance.timeoutAt"
                                        source="timeoutAt"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.currentNodeCode"
                                        source="currentNodeCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.currentNodeName"
                                        source="currentNodeName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.totalNodes"
                                        source="totalNodes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.completedNodes"
                                        source="completedNodes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.progressRate"
                                        source="progressRate"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.estimatedDurationMinutes"
                                        source="estimatedDurationMinutes"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.actualDurationMinutes"
                                        source="actualDurationMinutes"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstance.startTime"
                                        source="startTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstance.endTime"
                                        source="endTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.resultCode"
                                        source="resultCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.resultMessage"
                                        source="resultMessage"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.resultData"
                                        source="resultData"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstance.retryTimes"
                                        source="retryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstance.lastRetryTime"
                                        source="lastRetryTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.extParams"
                                        source="extParams"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstance.remark"
                                        source="remark"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default TaskInstanceCreate;
rsf-admin/src/page/taskInstance/TaskInstanceEdit.jsx
New file
@@ -0,0 +1,293 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const TaskInstanceEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.taskNo"
                                source="taskNo"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.bizNo"
                                source="bizNo"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.bizType"
                                source="bizType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.templateId"
                                source="templateId"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.templateCode"
                                source="templateCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.templateVersion"
                                source="templateVersion"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.sourceInfo"
                                source="sourceInfo"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.targetInfo"
                                source="targetInfo"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.sourceCode"
                                source="sourceCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.targetCode"
                                source="targetCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.plannedPath"
                                source="plannedPath"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.actualPath"
                                source="actualPath"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.priority"
                                source="priority"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstance.timeoutAt"
                                source="timeoutAt"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.currentNodeCode"
                                source="currentNodeCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.currentNodeName"
                                source="currentNodeName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.totalNodes"
                                source="totalNodes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.completedNodes"
                                source="completedNodes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.progressRate"
                                source="progressRate"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.estimatedDurationMinutes"
                                source="estimatedDurationMinutes"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.actualDurationMinutes"
                                source="actualDurationMinutes"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstance.startTime"
                                source="startTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstance.endTime"
                                source="endTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.resultCode"
                                source="resultCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.resultMessage"
                                source="resultMessage"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.resultData"
                                source="resultData"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstance.retryTimes"
                                source="retryTimes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstance.lastRetryTime"
                                source="lastRetryTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.extParams"
                                source="extParams"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstance.remark"
                                source="remark"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default TaskInstanceEdit;
rsf-admin/src/page/taskInstance/TaskInstanceList.jsx
New file
@@ -0,0 +1,210 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import TaskInstanceCreate from "./TaskInstanceCreate";
import TaskInstancePanel from "./TaskInstancePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="taskNo" label="table.field.taskInstance.taskNo" />,
    <TextInput source="bizNo" label="table.field.taskInstance.bizNo" />,
    <TextInput source="bizType" label="table.field.taskInstance.bizType" />,
    <NumberInput source="templateId" label="table.field.taskInstance.templateId" />,
    <TextInput source="templateCode" label="table.field.taskInstance.templateCode" />,
    <NumberInput source="templateVersion" label="table.field.taskInstance.templateVersion" />,
    <TextInput source="sourceInfo" label="table.field.taskInstance.sourceInfo" />,
    <TextInput source="targetInfo" label="table.field.taskInstance.targetInfo" />,
    <TextInput source="sourceCode" label="table.field.taskInstance.sourceCode" />,
    <TextInput source="targetCode" label="table.field.taskInstance.targetCode" />,
    <TextInput source="plannedPath" label="table.field.taskInstance.plannedPath" />,
    <TextInput source="actualPath" label="table.field.taskInstance.actualPath" />,
    <NumberInput source="priority" label="table.field.taskInstance.priority" />,
    <DateInput source="timeoutAt" label="table.field.taskInstance.timeoutAt" />,
    <TextInput source="currentNodeCode" label="table.field.taskInstance.currentNodeCode" />,
    <TextInput source="currentNodeName" label="table.field.taskInstance.currentNodeName" />,
    <NumberInput source="totalNodes" label="table.field.taskInstance.totalNodes" />,
    <NumberInput source="completedNodes" label="table.field.taskInstance.completedNodes" />,
    <NumberInput source="progressRate" label="table.field.taskInstance.progressRate" />,
    <NumberInput source="estimatedDurationMinutes" label="table.field.taskInstance.estimatedDurationMinutes" />,
    <NumberInput source="actualDurationMinutes" label="table.field.taskInstance.actualDurationMinutes" />,
    <DateInput source="startTime" label="table.field.taskInstance.startTime" />,
    <DateInput source="endTime" label="table.field.taskInstance.endTime" />,
    <TextInput source="resultCode" label="table.field.taskInstance.resultCode" />,
    <TextInput source="resultMessage" label="table.field.taskInstance.resultMessage" />,
    <TextInput source="resultData" label="table.field.taskInstance.resultData" />,
    <NumberInput source="retryTimes" label="table.field.taskInstance.retryTimes" />,
    <DateInput source="lastRetryTime" label="table.field.taskInstance.lastRetryTime" />,
    <TextInput source="extParams" label="table.field.taskInstance.extParams" />,
    <TextInput source="remark" label="table.field.taskInstance.remark" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const TaskInstanceList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.taskInstance"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='taskInstance' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='taskInstance'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <TaskInstancePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="taskNo" label="table.field.taskInstance.taskNo" />
                    <TextField source="bizNo" label="table.field.taskInstance.bizNo" />
                    <TextField source="bizType" label="table.field.taskInstance.bizType" />
                    <NumberField source="templateId" label="table.field.taskInstance.templateId" />
                    <TextField source="templateCode" label="table.field.taskInstance.templateCode" />
                    <NumberField source="templateVersion" label="table.field.taskInstance.templateVersion" />
                    <TextField source="sourceInfo" label="table.field.taskInstance.sourceInfo" />
                    <TextField source="targetInfo" label="table.field.taskInstance.targetInfo" />
                    <TextField source="sourceCode" label="table.field.taskInstance.sourceCode" />
                    <TextField source="targetCode" label="table.field.taskInstance.targetCode" />
                    <TextField source="plannedPath" label="table.field.taskInstance.plannedPath" />
                    <TextField source="actualPath" label="table.field.taskInstance.actualPath" />
                    <NumberField source="priority" label="table.field.taskInstance.priority" />
                    <DateField source="timeoutAt" label="table.field.taskInstance.timeoutAt" showTime />
                    <TextField source="currentNodeCode" label="table.field.taskInstance.currentNodeCode" />
                    <TextField source="currentNodeName" label="table.field.taskInstance.currentNodeName" />
                    <NumberField source="totalNodes" label="table.field.taskInstance.totalNodes" />
                    <NumberField source="completedNodes" label="table.field.taskInstance.completedNodes" />
                    <NumberField source="progressRate" label="table.field.taskInstance.progressRate" />
                    <NumberField source="estimatedDurationMinutes" label="table.field.taskInstance.estimatedDurationMinutes" />
                    <NumberField source="actualDurationMinutes" label="table.field.taskInstance.actualDurationMinutes" />
                    <DateField source="startTime" label="table.field.taskInstance.startTime" showTime />
                    <DateField source="endTime" label="table.field.taskInstance.endTime" showTime />
                    <TextField source="resultCode" label="table.field.taskInstance.resultCode" />
                    <TextField source="resultMessage" label="table.field.taskInstance.resultMessage" />
                    <TextField source="resultData" label="table.field.taskInstance.resultData" />
                    <NumberField source="retryTimes" label="table.field.taskInstance.retryTimes" />
                    <DateField source="lastRetryTime" label="table.field.taskInstance.lastRetryTime" showTime />
                    <TextField source="extParams" label="table.field.taskInstance.extParams" />
                    <TextField source="remark" label="table.field.taskInstance.remark" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <TaskInstanceCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='TaskInstance Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default TaskInstanceList;
rsf-admin/src/page/taskInstance/TaskInstancePanel.jsx
New file
@@ -0,0 +1,231 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const TaskInstancePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.taskInstance.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.taskNo"
                                property={record.taskNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.bizNo"
                                property={record.bizNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.bizType"
                                property={record.bizType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.templateId"
                                property={record.templateId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.templateCode"
                                property={record.templateCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.templateVersion"
                                property={record.templateVersion}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.sourceInfo"
                                property={record.sourceInfo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.targetInfo"
                                property={record.targetInfo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.sourceCode"
                                property={record.sourceCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.targetCode"
                                property={record.targetCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.plannedPath"
                                property={record.plannedPath}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.actualPath"
                                property={record.actualPath}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.priority"
                                property={record.priority}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.timeoutAt"
                                property={record.timeoutAt$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.currentNodeCode"
                                property={record.currentNodeCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.currentNodeName"
                                property={record.currentNodeName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.totalNodes"
                                property={record.totalNodes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.completedNodes"
                                property={record.completedNodes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.progressRate"
                                property={record.progressRate}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.estimatedDurationMinutes"
                                property={record.estimatedDurationMinutes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.actualDurationMinutes"
                                property={record.actualDurationMinutes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.startTime"
                                property={record.startTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.endTime"
                                property={record.endTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.resultCode"
                                property={record.resultCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.resultMessage"
                                property={record.resultMessage}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.resultData"
                                property={record.resultData}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.retryTimes"
                                property={record.retryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.lastRetryTime"
                                property={record.lastRetryTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.extParams"
                                property={record.extParams}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstance.remark"
                                property={record.remark}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default TaskInstancePanel;
rsf-admin/src/page/taskInstance/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import TaskInstanceList from "./TaskInstanceList";
import TaskInstanceEdit from "./TaskInstanceEdit";
export default {
    list: TaskInstanceList,
    edit: TaskInstanceEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeCreate.jsx
New file
@@ -0,0 +1,251 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const TaskInstanceNodeCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstanceNode.taskId"
                                        source="taskId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.taskNo"
                                        source="taskNo"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstanceNode.nodeOrder"
                                        source="nodeOrder"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.nodeCode"
                                        source="nodeCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.nodeName"
                                        source="nodeName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.nodeType"
                                        source="nodeType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.systemCode"
                                        source="systemCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.systemName"
                                        source="systemName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.executeParams"
                                        source="executeParams"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.executeResult"
                                        source="executeResult"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.errorCode"
                                        source="errorCode"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.errorMessage"
                                        source="errorMessage"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstanceNode.estimatedStartTime"
                                        source="estimatedStartTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstanceNode.actualStartTime"
                                        source="actualStartTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstanceNode.actualEndTime"
                                        source="actualEndTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskInstanceNode.timeoutAt"
                                        source="timeoutAt"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstanceNode.durationSeconds"
                                        source="durationSeconds"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstanceNode.retryTimes"
                                        source="retryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskInstanceNode.maxRetryTimes"
                                        source="maxRetryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskInstanceNode.dependsOnNodes"
                                        source="dependsOnNodes"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default TaskInstanceNodeCreate;
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeEdit.jsx
New file
@@ -0,0 +1,223 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const TaskInstanceNodeEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstanceNode.taskId"
                                source="taskId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.taskNo"
                                source="taskNo"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstanceNode.nodeOrder"
                                source="nodeOrder"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.nodeCode"
                                source="nodeCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.nodeName"
                                source="nodeName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.nodeType"
                                source="nodeType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.systemCode"
                                source="systemCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.systemName"
                                source="systemName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.executeParams"
                                source="executeParams"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.executeResult"
                                source="executeResult"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.errorCode"
                                source="errorCode"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.errorMessage"
                                source="errorMessage"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstanceNode.estimatedStartTime"
                                source="estimatedStartTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstanceNode.actualStartTime"
                                source="actualStartTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstanceNode.actualEndTime"
                                source="actualEndTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskInstanceNode.timeoutAt"
                                source="timeoutAt"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstanceNode.durationSeconds"
                                source="durationSeconds"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstanceNode.retryTimes"
                                source="retryTimes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskInstanceNode.maxRetryTimes"
                                source="maxRetryTimes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskInstanceNode.dependsOnNodes"
                                source="dependsOnNodes"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default TaskInstanceNodeEdit;
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodeList.jsx
New file
@@ -0,0 +1,190 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import TaskInstanceNodeCreate from "./TaskInstanceNodeCreate";
import TaskInstanceNodePanel from "./TaskInstanceNodePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="taskId" label="table.field.taskInstanceNode.taskId" />,
    <TextInput source="taskNo" label="table.field.taskInstanceNode.taskNo" />,
    <NumberInput source="nodeOrder" label="table.field.taskInstanceNode.nodeOrder" />,
    <TextInput source="nodeCode" label="table.field.taskInstanceNode.nodeCode" />,
    <TextInput source="nodeName" label="table.field.taskInstanceNode.nodeName" />,
    <TextInput source="nodeType" label="table.field.taskInstanceNode.nodeType" />,
    <TextInput source="systemCode" label="table.field.taskInstanceNode.systemCode" />,
    <TextInput source="systemName" label="table.field.taskInstanceNode.systemName" />,
    <TextInput source="executeParams" label="table.field.taskInstanceNode.executeParams" />,
    <TextInput source="executeResult" label="table.field.taskInstanceNode.executeResult" />,
    <TextInput source="errorCode" label="table.field.taskInstanceNode.errorCode" />,
    <TextInput source="errorMessage" label="table.field.taskInstanceNode.errorMessage" />,
    <DateInput source="estimatedStartTime" label="table.field.taskInstanceNode.estimatedStartTime" />,
    <DateInput source="actualStartTime" label="table.field.taskInstanceNode.actualStartTime" />,
    <DateInput source="actualEndTime" label="table.field.taskInstanceNode.actualEndTime" />,
    <DateInput source="timeoutAt" label="table.field.taskInstanceNode.timeoutAt" />,
    <NumberInput source="durationSeconds" label="table.field.taskInstanceNode.durationSeconds" />,
    <NumberInput source="retryTimes" label="table.field.taskInstanceNode.retryTimes" />,
    <NumberInput source="maxRetryTimes" label="table.field.taskInstanceNode.maxRetryTimes" />,
    <TextInput source="dependsOnNodes" label="table.field.taskInstanceNode.dependsOnNodes" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const TaskInstanceNodeList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.taskInstanceNode"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='taskInstanceNode' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='taskInstanceNode'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <TaskInstanceNodePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="taskId" label="table.field.taskInstanceNode.taskId" />
                    <TextField source="taskNo" label="table.field.taskInstanceNode.taskNo" />
                    <NumberField source="nodeOrder" label="table.field.taskInstanceNode.nodeOrder" />
                    <TextField source="nodeCode" label="table.field.taskInstanceNode.nodeCode" />
                    <TextField source="nodeName" label="table.field.taskInstanceNode.nodeName" />
                    <TextField source="nodeType" label="table.field.taskInstanceNode.nodeType" />
                    <TextField source="systemCode" label="table.field.taskInstanceNode.systemCode" />
                    <TextField source="systemName" label="table.field.taskInstanceNode.systemName" />
                    <TextField source="executeParams" label="table.field.taskInstanceNode.executeParams" />
                    <TextField source="executeResult" label="table.field.taskInstanceNode.executeResult" />
                    <TextField source="errorCode" label="table.field.taskInstanceNode.errorCode" />
                    <TextField source="errorMessage" label="table.field.taskInstanceNode.errorMessage" />
                    <DateField source="estimatedStartTime" label="table.field.taskInstanceNode.estimatedStartTime" showTime />
                    <DateField source="actualStartTime" label="table.field.taskInstanceNode.actualStartTime" showTime />
                    <DateField source="actualEndTime" label="table.field.taskInstanceNode.actualEndTime" showTime />
                    <DateField source="timeoutAt" label="table.field.taskInstanceNode.timeoutAt" showTime />
                    <NumberField source="durationSeconds" label="table.field.taskInstanceNode.durationSeconds" />
                    <NumberField source="retryTimes" label="table.field.taskInstanceNode.retryTimes" />
                    <NumberField source="maxRetryTimes" label="table.field.taskInstanceNode.maxRetryTimes" />
                    <TextField source="dependsOnNodes" label="table.field.taskInstanceNode.dependsOnNodes" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <TaskInstanceNodeCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='TaskInstanceNode Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default TaskInstanceNodeList;
rsf-admin/src/page/taskInstanceNode/TaskInstanceNodePanel.jsx
New file
@@ -0,0 +1,171 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const TaskInstanceNodePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.taskInstanceNode.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.taskId"
                                property={record.taskId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.taskNo"
                                property={record.taskNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.nodeOrder"
                                property={record.nodeOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.nodeCode"
                                property={record.nodeCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.nodeName"
                                property={record.nodeName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.nodeType"
                                property={record.nodeType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.systemCode"
                                property={record.systemCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.systemName"
                                property={record.systemName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.executeParams"
                                property={record.executeParams}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.executeResult"
                                property={record.executeResult}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.errorCode"
                                property={record.errorCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.errorMessage"
                                property={record.errorMessage}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.estimatedStartTime"
                                property={record.estimatedStartTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.actualStartTime"
                                property={record.actualStartTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.actualEndTime"
                                property={record.actualEndTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.timeoutAt"
                                property={record.timeoutAt$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.durationSeconds"
                                property={record.durationSeconds}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.retryTimes"
                                property={record.retryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.maxRetryTimes"
                                property={record.maxRetryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskInstanceNode.dependsOnNodes"
                                property={record.dependsOnNodes}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default TaskInstanceNodePanel;
rsf-admin/src/page/taskInstanceNode/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import TaskInstanceNodeList from "./TaskInstanceNodeList";
import TaskInstanceNodeEdit from "./TaskInstanceNodeEdit";
export default {
    list: TaskInstanceNodeList,
    edit: TaskInstanceNodeEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateCreate.jsx
New file
@@ -0,0 +1,244 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const TaskPathTemplateCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.templateCode"
                                        source="templateCode"
                                        parse={v => v}
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.templateName"
                                        source="templateName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.sourceType"
                                        source="sourceType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.targetType"
                                        source="targetType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.conditionExpression"
                                        source="conditionExpression"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.conditionDesc"
                                        source="conditionDesc"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.version"
                                        source="version"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.isCurrent"
                                        source="isCurrent"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskPathTemplate.effectiveTime"
                                        source="effectiveTime"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskPathTemplate.expireTime"
                                        source="expireTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.priority"
                                        source="priority"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.timeoutMinutes"
                                        source="timeoutMinutes"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.maxRetryTimes"
                                        source="maxRetryTimes"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplate.retryIntervalSeconds"
                                        source="retryIntervalSeconds"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.remark"
                                        source="remark"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.createdBy"
                                        source="createdBy"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplate.updatedBy"
                                        source="updatedBy"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskPathTemplate.createdTime"
                                        source="createdTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <DateInput
                                        label="table.field.taskPathTemplate.updatedTime"
                                        source="updatedTime"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default TaskPathTemplateCreate;
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateEdit.jsx
New file
@@ -0,0 +1,216 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const TaskPathTemplateEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.templateCode"
                                source="templateCode"
                                parse={v => v}
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.templateName"
                                source="templateName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.sourceType"
                                source="sourceType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.targetType"
                                source="targetType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.conditionExpression"
                                source="conditionExpression"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.conditionDesc"
                                source="conditionDesc"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.version"
                                source="version"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.isCurrent"
                                source="isCurrent"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskPathTemplate.effectiveTime"
                                source="effectiveTime"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskPathTemplate.expireTime"
                                source="expireTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.priority"
                                source="priority"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.timeoutMinutes"
                                source="timeoutMinutes"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.maxRetryTimes"
                                source="maxRetryTimes"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplate.retryIntervalSeconds"
                                source="retryIntervalSeconds"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.remark"
                                source="remark"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.createdBy"
                                source="createdBy"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplate.updatedBy"
                                source="updatedBy"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskPathTemplate.createdTime"
                                source="createdTime"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <DateInput
                                label="table.field.taskPathTemplate.updatedTime"
                                source="updatedTime"
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default TaskPathTemplateEdit;
rsf-admin/src/page/taskPathTemplate/TaskPathTemplateList.jsx
New file
@@ -0,0 +1,188 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import TaskPathTemplateCreate from "./TaskPathTemplateCreate";
import TaskPathTemplatePanel from "./TaskPathTemplatePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <TextInput source="templateCode" label="table.field.taskPathTemplate.templateCode" />,
    <TextInput source="templateName" label="table.field.taskPathTemplate.templateName" />,
    <TextInput source="sourceType" label="table.field.taskPathTemplate.sourceType" />,
    <TextInput source="targetType" label="table.field.taskPathTemplate.targetType" />,
    <TextInput source="conditionExpression" label="table.field.taskPathTemplate.conditionExpression" />,
    <TextInput source="conditionDesc" label="table.field.taskPathTemplate.conditionDesc" />,
    <NumberInput source="version" label="table.field.taskPathTemplate.version" />,
    <NumberInput source="isCurrent" label="table.field.taskPathTemplate.isCurrent" />,
    <DateInput source="effectiveTime" label="table.field.taskPathTemplate.effectiveTime" />,
    <DateInput source="expireTime" label="table.field.taskPathTemplate.expireTime" />,
    <NumberInput source="priority" label="table.field.taskPathTemplate.priority" />,
    <NumberInput source="timeoutMinutes" label="table.field.taskPathTemplate.timeoutMinutes" />,
    <NumberInput source="maxRetryTimes" label="table.field.taskPathTemplate.maxRetryTimes" />,
    <NumberInput source="retryIntervalSeconds" label="table.field.taskPathTemplate.retryIntervalSeconds" />,
    <TextInput source="remark" label="table.field.taskPathTemplate.remark" />,
    <TextInput source="createdBy" label="table.field.taskPathTemplate.createdBy" />,
    <TextInput source="updatedBy" label="table.field.taskPathTemplate.updatedBy" />,
    <DateInput source="createdTime" label="table.field.taskPathTemplate.createdTime" />,
    <DateInput source="updatedTime" label="table.field.taskPathTemplate.updatedTime" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const TaskPathTemplateList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.taskPathTemplate"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='taskPathTemplate' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='taskPathTemplate'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <TaskPathTemplatePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <TextField source="templateCode" label="table.field.taskPathTemplate.templateCode" />
                    <TextField source="templateName" label="table.field.taskPathTemplate.templateName" />
                    <TextField source="sourceType" label="table.field.taskPathTemplate.sourceType" />
                    <TextField source="targetType" label="table.field.taskPathTemplate.targetType" />
                    <TextField source="conditionExpression" label="table.field.taskPathTemplate.conditionExpression" />
                    <TextField source="conditionDesc" label="table.field.taskPathTemplate.conditionDesc" />
                    <NumberField source="version" label="table.field.taskPathTemplate.version" />
                    <NumberField source="isCurrent" label="table.field.taskPathTemplate.isCurrent" />
                    <DateField source="effectiveTime" label="table.field.taskPathTemplate.effectiveTime" showTime />
                    <DateField source="expireTime" label="table.field.taskPathTemplate.expireTime" showTime />
                    <NumberField source="priority" label="table.field.taskPathTemplate.priority" />
                    <NumberField source="timeoutMinutes" label="table.field.taskPathTemplate.timeoutMinutes" />
                    <NumberField source="maxRetryTimes" label="table.field.taskPathTemplate.maxRetryTimes" />
                    <NumberField source="retryIntervalSeconds" label="table.field.taskPathTemplate.retryIntervalSeconds" />
                    <TextField source="remark" label="table.field.taskPathTemplate.remark" />
                    <TextField source="createdBy" label="table.field.taskPathTemplate.createdBy" />
                    <TextField source="updatedBy" label="table.field.taskPathTemplate.updatedBy" />
                    <DateField source="createdTime" label="table.field.taskPathTemplate.createdTime" showTime />
                    <DateField source="updatedTime" label="table.field.taskPathTemplate.updatedTime" showTime />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <TaskPathTemplateCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='TaskPathTemplate Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default TaskPathTemplateList;
rsf-admin/src/page/taskPathTemplate/TaskPathTemplatePanel.jsx
New file
@@ -0,0 +1,165 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const TaskPathTemplatePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.taskPathTemplate.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.templateCode"
                                property={record.templateCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.templateName"
                                property={record.templateName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.sourceType"
                                property={record.sourceType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.targetType"
                                property={record.targetType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.conditionExpression"
                                property={record.conditionExpression}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.conditionDesc"
                                property={record.conditionDesc}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.version"
                                property={record.version}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.isCurrent"
                                property={record.isCurrent}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.effectiveTime"
                                property={record.effectiveTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.expireTime"
                                property={record.expireTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.priority"
                                property={record.priority}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.timeoutMinutes"
                                property={record.timeoutMinutes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.maxRetryTimes"
                                property={record.maxRetryTimes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.retryIntervalSeconds"
                                property={record.retryIntervalSeconds}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.remark"
                                property={record.remark}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.createdBy"
                                property={record.createdBy}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.updatedBy"
                                property={record.updatedBy}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.createdTime"
                                property={record.createdTime$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplate.updatedTime"
                                property={record.updatedTime$}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default TaskPathTemplatePanel;
rsf-admin/src/page/taskPathTemplate/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import TaskPathTemplateList from "./TaskPathTemplateList";
import TaskPathTemplateEdit from "./TaskPathTemplateEdit";
export default {
    list: TaskPathTemplateList,
    edit: TaskPathTemplateEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeCreate.jsx
New file
@@ -0,0 +1,226 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    CreateBase,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SaveButton,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    Toolbar,
    required,
    useDataProvider,
    useNotify,
    Form,
    useCreateController,
} from 'react-admin';
import {
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Stack,
    Grid,
    Box,
} from '@mui/material';
import DialogCloseButton from "../components/DialogCloseButton";
import StatusSelectInput from "../components/StatusSelectInput";
import MemoInput from "../components/MemoInput";
const TaskPathTemplateNodeCreate = (props) => {
    const { open, setOpen } = props;
    const translate = useTranslate();
    const notify = useNotify();
    const handleClose = (event, reason) => {
        if (reason !== "backdropClick") {
            setOpen(false);
        }
    };
    const handleSuccess = async (data) => {
        setOpen(false);
        notify('common.response.success');
    };
    const handleError = async (error) => {
        notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } });
    };
    return (
        <>
            <CreateBase
                record={{}}
                transform={(data) => {
                    return data;
                }}
                mutationOptions={{ onSuccess: handleSuccess, onError: handleError }}
            >
                <Dialog
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="form-dialog-title"
                    fullWidth
                    disableRestoreFocus
                    maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl'
                >
                    <Form>
                        <DialogTitle id="form-dialog-title" sx={{
                            position: 'sticky',
                            top: 0,
                            backgroundColor: 'background.paper',
                            zIndex: 1000
                        }}
                        >
                            {translate('create.title')}
                            <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}>
                                <DialogCloseButton onClose={handleClose} />
                            </Box>
                        </DialogTitle>
                        <DialogContent sx={{ mt: 2 }}>
                            <Grid container rowSpacing={2} columnSpacing={2}>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplateNode.templateId"
                                        source="templateId"
                                        autoFocus
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.templateCode"
                                        source="templateCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplateNode.nodeOrder"
                                        source="nodeOrder"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.nodeCode"
                                        source="nodeCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.nodeName"
                                        source="nodeName"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.nodeType"
                                        source="nodeType"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.systemCode"
                                        source="systemCode"
                                        parse={v => v}
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.systemName"
                                        source="systemName"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.executeParams"
                                        source="executeParams"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.resultSchema"
                                        source="resultSchema"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplateNode.timeoutMinutes"
                                        source="timeoutMinutes"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplateNode.mandatory"
                                        source="mandatory"
                                        validate={required()}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <NumberInput
                                        label="table.field.taskPathTemplateNode.parallelExecutable"
                                        source="parallelExecutable"
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.preCondition"
                                        source="preCondition"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.postCondition"
                                        source="postCondition"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <TextInput
                                        label="table.field.taskPathTemplateNode.nextNodeRules"
                                        source="nextNodeRules"
                                        parse={v => v}
                                    />
                                </Grid>
                                <Grid item xs={6} display="flex" gap={1}>
                                    <StatusSelectInput />
                                </Grid>
                                <Grid item xs={12} display="flex" gap={1}>
                                    <Stack direction="column" spacing={1} width={'100%'}>
                                        <MemoInput />
                                    </Stack>
                                </Grid>
                            </Grid>
                        </DialogContent>
                        <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}>
                            <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  >
                                <SaveButton />
                            </Toolbar>
                        </DialogActions>
                    </Form>
                </Dialog>
            </CreateBase>
        </>
    )
}
export default TaskPathTemplateNodeCreate;
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeEdit.jsx
New file
@@ -0,0 +1,198 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    Edit,
    SimpleForm,
    FormDataConsumer,
    useTranslate,
    TextInput,
    NumberInput,
    BooleanInput,
    DateInput,
    SelectInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    SaveButton,
    Toolbar,
    Labeled,
    NumberField,
    required,
    useRecordContext,
    DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
import { Stack, Grid, Box, Typography } from '@mui/material';
import * as Common from '@/utils/common';
import { EDIT_MODE, REFERENCE_INPUT_PAGESIZE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
import MemoInput from "../components/MemoInput";
import StatusSelectInput from "../components/StatusSelectInput";
const FormToolbar = () => {
    const { getValues } = useFormContext();
    return (
        <Toolbar sx={{ justifyContent: 'space-between' }}>
            <SaveButton />
            <DeleteButton mutationMode="optimistic" />
        </Toolbar>
    )
}
const TaskPathTemplateNodeEdit = () => {
    const translate = useTranslate();
    return (
        <Edit
            redirect="list"
            mutationMode={EDIT_MODE}
            actions={<CustomerTopToolBar />}
            aside={<EditBaseAside />}
        >
            <SimpleForm
                shouldUnregister
                warnWhenUnsavedChanges
                toolbar={<FormToolbar />}
                mode="onTouched"
                defaultValues={{}}
            // validate={(values) => { }}
            >
                <Grid container width={{ xs: '100%', xl: '80%' }} rowSpacing={3} columnSpacing={3}>
                    <Grid item xs={12} md={8}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.main')}
                        </Typography>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplateNode.templateId"
                                source="templateId"
                                autoFocus
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.templateCode"
                                source="templateCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplateNode.nodeOrder"
                                source="nodeOrder"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.nodeCode"
                                source="nodeCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.nodeName"
                                source="nodeName"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.nodeType"
                                source="nodeType"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.systemCode"
                                source="systemCode"
                                parse={v => v}
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.systemName"
                                source="systemName"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.executeParams"
                                source="executeParams"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.resultSchema"
                                source="resultSchema"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplateNode.timeoutMinutes"
                                source="timeoutMinutes"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplateNode.mandatory"
                                source="mandatory"
                                validate={required()}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <NumberInput
                                label="table.field.taskPathTemplateNode.parallelExecutable"
                                source="parallelExecutable"
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.preCondition"
                                source="preCondition"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.postCondition"
                                source="postCondition"
                                parse={v => v}
                            />
                        </Stack>
                        <Stack direction='row' gap={2}>
                            <TextInput
                                label="table.field.taskPathTemplateNode.nextNodeRules"
                                source="nextNodeRules"
                                parse={v => v}
                            />
                        </Stack>
                    </Grid>
                    <Grid item xs={12} md={4}>
                        <Typography variant="h6" gutterBottom>
                            {translate('common.edit.title.common')}
                        </Typography>
                        <StatusSelectInput />
                        <Box mt="2em" />
                        <MemoInput />
                    </Grid>
                </Grid>
            </SimpleForm>
        </Edit >
    )
}
export default TaskPathTemplateNodeEdit;
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodeList.jsx
New file
@@ -0,0 +1,182 @@
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
import { useNavigate } from 'react-router-dom';
import {
    List,
    DatagridConfigurable,
    SearchInput,
    TopToolbar,
    SelectColumnsButton,
    EditButton,
    FilterButton,
    CreateButton,
    ExportButton,
    BulkDeleteButton,
    WrapperField,
    useRecordContext,
    useTranslate,
    useNotify,
    useListContext,
    FunctionField,
    TextField,
    NumberField,
    DateField,
    BooleanField,
    ReferenceField,
    TextInput,
    DateTimeInput,
    DateInput,
    SelectInput,
    NumberInput,
    ReferenceInput,
    ReferenceArrayInput,
    AutocompleteInput,
    DeleteButton,
} from 'react-admin';
import { Box, Typography, Card, Stack } from '@mui/material';
import { styled } from '@mui/material/styles';
import TaskPathTemplateNodeCreate from "./TaskPathTemplateNodeCreate";
import TaskPathTemplateNodePanel from "./TaskPathTemplateNodePanel";
import EmptyData from "../components/EmptyData";
import MyCreateButton from "../components/MyCreateButton";
import MyExportButton from '../components/MyExportButton';
import PageDrawer from "../components/PageDrawer";
import MyField from "../components/MyField";
import { PAGE_DRAWER_WIDTH, OPERATE_MODE, DEFAULT_PAGE_SIZE } from '@/config/setting';
import * as Common from '@/utils/common';
const StyledDatagrid = styled(DatagridConfigurable)(({ theme }) => ({
    '& .css-1vooibu-MuiSvgIcon-root': {
        height: '.9em'
    },
    '& .RaDatagrid-row': {
        cursor: 'auto'
    },
    '& .column-name': {
    },
    '& .opt': {
        width: 200
    },
}));
const filters = [
    <SearchInput source="condition" alwaysOn />,
    <DateInput label='common.time.after' source="timeStart" alwaysOn />,
    <DateInput label='common.time.before' source="timeEnd" alwaysOn />,
    <NumberInput source="templateId" label="table.field.taskPathTemplateNode.templateId" />,
    <TextInput source="templateCode" label="table.field.taskPathTemplateNode.templateCode" />,
    <NumberInput source="nodeOrder" label="table.field.taskPathTemplateNode.nodeOrder" />,
    <TextInput source="nodeCode" label="table.field.taskPathTemplateNode.nodeCode" />,
    <TextInput source="nodeName" label="table.field.taskPathTemplateNode.nodeName" />,
    <TextInput source="nodeType" label="table.field.taskPathTemplateNode.nodeType" />,
    <TextInput source="systemCode" label="table.field.taskPathTemplateNode.systemCode" />,
    <TextInput source="systemName" label="table.field.taskPathTemplateNode.systemName" />,
    <TextInput source="executeParams" label="table.field.taskPathTemplateNode.executeParams" />,
    <TextInput source="resultSchema" label="table.field.taskPathTemplateNode.resultSchema" />,
    <NumberInput source="timeoutMinutes" label="table.field.taskPathTemplateNode.timeoutMinutes" />,
    <NumberInput source="mandatory" label="table.field.taskPathTemplateNode.mandatory" />,
    <NumberInput source="parallelExecutable" label="table.field.taskPathTemplateNode.parallelExecutable" />,
    <TextInput source="preCondition" label="table.field.taskPathTemplateNode.preCondition" />,
    <TextInput source="postCondition" label="table.field.taskPathTemplateNode.postCondition" />,
    <TextInput source="nextNodeRules" label="table.field.taskPathTemplateNode.nextNodeRules" />,
    <TextInput label="common.field.memo" source="memo" />,
    <SelectInput
        label="common.field.status"
        source="status"
        choices={[
            { id: '1', name: 'common.enums.statusTrue' },
            { id: '0', name: 'common.enums.statusFalse' },
        ]}
        resettable
    />,
]
const TaskPathTemplateNodeList = () => {
    const translate = useTranslate();
    const [createDialog, setCreateDialog] = useState(false);
    const [drawerVal, setDrawerVal] = useState(false);
    return (
        <Box display="flex">
            <List
                sx={{
                    flexGrow: 1,
                    transition: (theme) =>
                        theme.transitions.create(['all'], {
                            duration: theme.transitions.duration.enteringScreen,
                        }),
                    marginRight: !!drawerVal ? `${PAGE_DRAWER_WIDTH}px` : 0,
                }}
                title={"menu.taskPathTemplateNode"}
                empty={<EmptyData onClick={() => { setCreateDialog(true) }} />}
                filters={filters}
                sort={{ field: "create_time", order: "desc" }}
                actions={(
                    <TopToolbar>
                        <FilterButton />
                        <MyCreateButton onClick={() => { setCreateDialog(true) }} />
                        <SelectColumnsButton preferenceKey='taskPathTemplateNode' />
                        <MyExportButton />
                    </TopToolbar>
                )}
                perPage={DEFAULT_PAGE_SIZE}
            >
                <StyledDatagrid
                    preferenceKey='taskPathTemplateNode'
                    bulkActionButtons={() => <BulkDeleteButton mutationMode={OPERATE_MODE} />}
                    rowClick={(id, resource, record) => false}
                    expand={() => <TaskPathTemplateNodePanel />}
                    expandSingle={true}
                    omit={['id', 'createTime', 'createBy', 'memo']}
                >
                    <NumberField source="id" />
                    <NumberField source="templateId" label="table.field.taskPathTemplateNode.templateId" />
                    <TextField source="templateCode" label="table.field.taskPathTemplateNode.templateCode" />
                    <NumberField source="nodeOrder" label="table.field.taskPathTemplateNode.nodeOrder" />
                    <TextField source="nodeCode" label="table.field.taskPathTemplateNode.nodeCode" />
                    <TextField source="nodeName" label="table.field.taskPathTemplateNode.nodeName" />
                    <TextField source="nodeType" label="table.field.taskPathTemplateNode.nodeType" />
                    <TextField source="systemCode" label="table.field.taskPathTemplateNode.systemCode" />
                    <TextField source="systemName" label="table.field.taskPathTemplateNode.systemName" />
                    <TextField source="executeParams" label="table.field.taskPathTemplateNode.executeParams" />
                    <TextField source="resultSchema" label="table.field.taskPathTemplateNode.resultSchema" />
                    <NumberField source="timeoutMinutes" label="table.field.taskPathTemplateNode.timeoutMinutes" />
                    <NumberField source="mandatory" label="table.field.taskPathTemplateNode.mandatory" />
                    <NumberField source="parallelExecutable" label="table.field.taskPathTemplateNode.parallelExecutable" />
                    <TextField source="preCondition" label="table.field.taskPathTemplateNode.preCondition" />
                    <TextField source="postCondition" label="table.field.taskPathTemplateNode.postCondition" />
                    <TextField source="nextNodeRules" label="table.field.taskPathTemplateNode.nextNodeRules" />
                    <ReferenceField source="updateBy" label="common.field.updateBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="updateTime" label="common.field.updateTime" showTime />
                    <ReferenceField source="createBy" label="common.field.createBy" reference="user" link={false} sortable={false}>
                        <TextField source="nickname" />
                    </ReferenceField>
                    <DateField source="createTime" label="common.field.createTime" showTime />
                    <BooleanField source="statusBool" label="common.field.status" sortable={false} />
                    <TextField source="memo" label="common.field.memo" sortable={false} />
                    <WrapperField cellClassName="opt" label="common.field.opt">
                        <EditButton sx={{ padding: '1px', fontSize: '.75rem' }} />
                        <DeleteButton sx={{ padding: '1px', fontSize: '.75rem' }} mutationMode={OPERATE_MODE} />
                    </WrapperField>
                </StyledDatagrid>
            </List>
            <TaskPathTemplateNodeCreate
                open={createDialog}
                setOpen={setCreateDialog}
            />
            <PageDrawer
                title='TaskPathTemplateNode Detail'
                drawerVal={drawerVal}
                setDrawerVal={setDrawerVal}
            >
            </PageDrawer>
        </Box>
    )
}
export default TaskPathTemplateNodeList;
rsf-admin/src/page/taskPathTemplateNode/TaskPathTemplateNodePanel.jsx
New file
@@ -0,0 +1,147 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import {
    useTranslate,
    useRecordContext,
} from 'react-admin';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const TaskPathTemplateNodePanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.taskPathTemplateNode.id'))}: {record.id}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.templateId"
                                property={record.templateId}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.templateCode"
                                property={record.templateCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.nodeOrder"
                                property={record.nodeOrder}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.nodeCode"
                                property={record.nodeCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.nodeName"
                                property={record.nodeName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.nodeType"
                                property={record.nodeType}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.systemCode"
                                property={record.systemCode}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.systemName"
                                property={record.systemName}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.executeParams"
                                property={record.executeParams}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.resultSchema"
                                property={record.resultSchema}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.timeoutMinutes"
                                property={record.timeoutMinutes}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.mandatory"
                                property={record.mandatory}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.parallelExecutable"
                                property={record.parallelExecutable}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.preCondition"
                                property={record.preCondition}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.postCondition"
                                property={record.postCondition}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.taskPathTemplateNode.nextNodeRules"
                                property={record.nextNodeRules}
                            />
                        </Grid>
                    </Grid>
                </CardContent>
            </Card >
        </>
    );
};
export default TaskPathTemplateNodePanel;
rsf-admin/src/page/taskPathTemplateNode/index.jsx
New file
@@ -0,0 +1,18 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import {
    ListGuesser,
    EditGuesser,
    ShowGuesser,
} from "react-admin";
import TaskPathTemplateNodeList from "./TaskPathTemplateNodeList";
import TaskPathTemplateNodeEdit from "./TaskPathTemplateNodeEdit";
export default {
    list: TaskPathTemplateNodeList,
    edit: TaskPathTemplateNodeEdit,
    show: ShowGuesser,
    recordRepresentation: (record) => {
        return `${record.id}`
    }
};
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowInstanceController.java
New file
@@ -0,0 +1,107 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.FlowInstance;
import com.vincent.rsf.server.system.service.FlowInstanceService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class FlowInstanceController extends BaseController {
    @Autowired
    private FlowInstanceService flowInstanceService;
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @PostMapping("/flowInstance/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<FlowInstance, BaseParam> pageParam = new PageParam<>(baseParam, FlowInstance.class);
        return R.ok().add(flowInstanceService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @PostMapping("/flowInstance/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(flowInstanceService.list());
    }
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @PostMapping({"/flowInstance/many/{ids}", "/flowInstances/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(flowInstanceService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @GetMapping("/flowInstance/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(flowInstanceService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:flowInstance:save')")
    @OperationLog("Create 实例化子流程主表")
    @PostMapping("/flowInstance/save")
    public R save(@RequestBody FlowInstance flowInstance) {
        flowInstance.setCreateTime(new Date());
        flowInstance.setUpdateTime(new Date());
        if (!flowInstanceService.save(flowInstance)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(flowInstance);
    }
    @PreAuthorize("hasAuthority('system:flowInstance:update')")
    @OperationLog("Update 实例化子流程主表")
    @PostMapping("/flowInstance/update")
    public R update(@RequestBody FlowInstance flowInstance) {
        flowInstance.setUpdateTime(new Date());
        if (!flowInstanceService.updateById(flowInstance)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(flowInstance);
    }
    @PreAuthorize("hasAuthority('system:flowInstance:remove')")
    @OperationLog("Delete 实例化子流程主表")
    @PostMapping("/flowInstance/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!flowInstanceService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @PostMapping("/flowInstance/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<FlowInstance> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(FlowInstance::getId, condition);
        }
        flowInstanceService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:flowInstance:list')")
    @PostMapping("/flowInstance/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(flowInstanceService.list(), FlowInstance.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepInstanceController.java
New file
@@ -0,0 +1,107 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.FlowStepInstance;
import com.vincent.rsf.server.system.service.FlowStepInstanceService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class FlowStepInstanceController extends BaseController {
    @Autowired
    private FlowStepInstanceService flowStepInstanceService;
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @PostMapping("/flowStepInstance/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<FlowStepInstance, BaseParam> pageParam = new PageParam<>(baseParam, FlowStepInstance.class);
        return R.ok().add(flowStepInstanceService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @PostMapping("/flowStepInstance/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(flowStepInstanceService.list());
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @PostMapping({"/flowStepInstance/many/{ids}", "/flowStepInstances/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(flowStepInstanceService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @GetMapping("/flowStepInstance/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(flowStepInstanceService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:save')")
    @OperationLog("Create 子流程步骤实例")
    @PostMapping("/flowStepInstance/save")
    public R save(@RequestBody FlowStepInstance flowStepInstance) {
        flowStepInstance.setCreateTime(new Date());
        flowStepInstance.setUpdateTime(new Date());
        if (!flowStepInstanceService.save(flowStepInstance)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(flowStepInstance);
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:update')")
    @OperationLog("Update 子流程步骤实例")
    @PostMapping("/flowStepInstance/update")
    public R update(@RequestBody FlowStepInstance flowStepInstance) {
        flowStepInstance.setUpdateTime(new Date());
        if (!flowStepInstanceService.updateById(flowStepInstance)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(flowStepInstance);
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:remove')")
    @OperationLog("Delete 子流程步骤实例")
    @PostMapping("/flowStepInstance/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!flowStepInstanceService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @PostMapping("/flowStepInstance/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<FlowStepInstance> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(FlowStepInstance::getId, condition);
        }
        flowStepInstanceService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:flowStepInstance:list')")
    @PostMapping("/flowStepInstance/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(flowStepInstanceService.list(), FlowStepInstance.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepLogController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.FlowStepLog;
import com.vincent.rsf.server.system.service.FlowStepLogService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class FlowStepLogController extends BaseController {
    @Autowired
    private FlowStepLogService flowStepLogService;
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @PostMapping("/flowStepLog/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<FlowStepLog, BaseParam> pageParam = new PageParam<>(baseParam, FlowStepLog.class);
        return R.ok().add(flowStepLogService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @PostMapping("/flowStepLog/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(flowStepLogService.list());
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @PostMapping({"/flowStepLog/many/{ids}", "/flowStepLogs/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(flowStepLogService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @GetMapping("/flowStepLog/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(flowStepLogService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:save')")
    @OperationLog("Create 步骤执行日志")
    @PostMapping("/flowStepLog/save")
    public R save(@RequestBody FlowStepLog flowStepLog) {
        flowStepLog.setCreateBy(getLoginUserId());
        flowStepLog.setCreateTime(new Date());
        flowStepLog.setUpdateBy(getLoginUserId());
        flowStepLog.setUpdateTime(new Date());
        if (!flowStepLogService.save(flowStepLog)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(flowStepLog);
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:update')")
    @OperationLog("Update 步骤执行日志")
    @PostMapping("/flowStepLog/update")
    public R update(@RequestBody FlowStepLog flowStepLog) {
        flowStepLog.setUpdateBy(getLoginUserId());
        flowStepLog.setUpdateTime(new Date());
        if (!flowStepLogService.updateById(flowStepLog)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(flowStepLog);
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:remove')")
    @OperationLog("Delete 步骤执行日志")
    @PostMapping("/flowStepLog/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!flowStepLogService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @PostMapping("/flowStepLog/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<FlowStepLog> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(FlowStepLog::getId, condition);
        }
        flowStepLogService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:flowStepLog:list')")
    @PostMapping("/flowStepLog/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(flowStepLogService.list(), FlowStepLog.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/FlowStepTemplateController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.FlowStepTemplate;
import com.vincent.rsf.server.system.service.FlowStepTemplateService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class FlowStepTemplateController extends BaseController {
    @Autowired
    private FlowStepTemplateService flowStepTemplateService;
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @PostMapping("/flowStepTemplate/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<FlowStepTemplate, BaseParam> pageParam = new PageParam<>(baseParam, FlowStepTemplate.class);
        return R.ok().add(flowStepTemplateService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @PostMapping("/flowStepTemplate/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(flowStepTemplateService.list());
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @PostMapping({"/flowStepTemplate/many/{ids}", "/flowStepTemplates/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(flowStepTemplateService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @GetMapping("/flowStepTemplate/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(flowStepTemplateService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:save')")
    @OperationLog("Create 子流程步骤模板")
    @PostMapping("/flowStepTemplate/save")
    public R save(@RequestBody FlowStepTemplate flowStepTemplate) {
        flowStepTemplate.setCreateBy(getLoginUserId());
        flowStepTemplate.setCreateTime(new Date());
        flowStepTemplate.setUpdateBy(getLoginUserId());
        flowStepTemplate.setUpdateTime(new Date());
        if (!flowStepTemplateService.save(flowStepTemplate)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(flowStepTemplate);
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:update')")
    @OperationLog("Update 子流程步骤模板")
    @PostMapping("/flowStepTemplate/update")
    public R update(@RequestBody FlowStepTemplate flowStepTemplate) {
        flowStepTemplate.setUpdateBy(getLoginUserId());
        flowStepTemplate.setUpdateTime(new Date());
        if (!flowStepTemplateService.updateById(flowStepTemplate)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(flowStepTemplate);
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:remove')")
    @OperationLog("Delete 子流程步骤模板")
    @PostMapping("/flowStepTemplate/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!flowStepTemplateService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @PostMapping("/flowStepTemplate/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<FlowStepTemplate> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(FlowStepTemplate::getId, condition);
        }
        flowStepTemplateService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:flowStepTemplate:list')")
    @PostMapping("/flowStepTemplate/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(flowStepTemplateService.list(), FlowStepTemplate.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/SubsystemFlowTemplateController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.SubsystemFlowTemplate;
import com.vincent.rsf.server.system.service.SubsystemFlowTemplateService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class SubsystemFlowTemplateController extends BaseController {
    @Autowired
    private SubsystemFlowTemplateService subsystemFlowTemplateService;
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @PostMapping("/subsystemFlowTemplate/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<SubsystemFlowTemplate, BaseParam> pageParam = new PageParam<>(baseParam, SubsystemFlowTemplate.class);
        return R.ok().add(subsystemFlowTemplateService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @PostMapping("/subsystemFlowTemplate/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(subsystemFlowTemplateService.list());
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @PostMapping({"/subsystemFlowTemplate/many/{ids}", "/subsystemFlowTemplates/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(subsystemFlowTemplateService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @GetMapping("/subsystemFlowTemplate/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(subsystemFlowTemplateService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:save')")
    @OperationLog("Create 子系统模板")
    @PostMapping("/subsystemFlowTemplate/save")
    public R save(@RequestBody SubsystemFlowTemplate subsystemFlowTemplate) {
        subsystemFlowTemplate.setCreateBy(getLoginUserId());
        subsystemFlowTemplate.setCreateTime(new Date());
        subsystemFlowTemplate.setUpdateBy(getLoginUserId());
        subsystemFlowTemplate.setUpdateTime(new Date());
        if (!subsystemFlowTemplateService.save(subsystemFlowTemplate)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(subsystemFlowTemplate);
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:update')")
    @OperationLog("Update 子系统模板")
    @PostMapping("/subsystemFlowTemplate/update")
    public R update(@RequestBody SubsystemFlowTemplate subsystemFlowTemplate) {
        subsystemFlowTemplate.setUpdateBy(getLoginUserId());
        subsystemFlowTemplate.setUpdateTime(new Date());
        if (!subsystemFlowTemplateService.updateById(subsystemFlowTemplate)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(subsystemFlowTemplate);
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:remove')")
    @OperationLog("Delete 子系统模板")
    @PostMapping("/subsystemFlowTemplate/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!subsystemFlowTemplateService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @PostMapping("/subsystemFlowTemplate/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<SubsystemFlowTemplate> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(SubsystemFlowTemplate::getId, condition);
        }
        subsystemFlowTemplateService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:subsystemFlowTemplate:list')")
    @PostMapping("/subsystemFlowTemplate/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(subsystemFlowTemplateService.list(), SubsystemFlowTemplate.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskInstanceController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.TaskInstance;
import com.vincent.rsf.server.system.service.TaskInstanceService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class TaskInstanceController extends BaseController {
    @Autowired
    private TaskInstanceService taskInstanceService;
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @PostMapping("/taskInstance/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<TaskInstance, BaseParam> pageParam = new PageParam<>(baseParam, TaskInstance.class);
        return R.ok().add(taskInstanceService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @PostMapping("/taskInstance/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(taskInstanceService.list());
    }
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @PostMapping({"/taskInstance/many/{ids}", "/taskInstances/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(taskInstanceService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @GetMapping("/taskInstance/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(taskInstanceService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:taskInstance:save')")
    @OperationLog("Create 物料权限")
    @PostMapping("/taskInstance/save")
    public R save(@RequestBody TaskInstance taskInstance) {
        taskInstance.setCreateBy(getLoginUserId());
        taskInstance.setCreateTime(new Date());
        taskInstance.setUpdateBy(getLoginUserId());
        taskInstance.setUpdateTime(new Date());
        if (!taskInstanceService.save(taskInstance)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(taskInstance);
    }
    @PreAuthorize("hasAuthority('system:taskInstance:update')")
    @OperationLog("Update 物料权限")
    @PostMapping("/taskInstance/update")
    public R update(@RequestBody TaskInstance taskInstance) {
        taskInstance.setUpdateBy(getLoginUserId());
        taskInstance.setUpdateTime(new Date());
        if (!taskInstanceService.updateById(taskInstance)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(taskInstance);
    }
    @PreAuthorize("hasAuthority('system:taskInstance:remove')")
    @OperationLog("Delete 物料权限")
    @PostMapping("/taskInstance/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!taskInstanceService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @PostMapping("/taskInstance/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<TaskInstance> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(TaskInstance::getId, condition);
        }
        taskInstanceService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:taskInstance:list')")
    @PostMapping("/taskInstance/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(taskInstanceService.list(), TaskInstance.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskInstanceNodeController.java
New file
@@ -0,0 +1,107 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.TaskInstanceNode;
import com.vincent.rsf.server.system.service.TaskInstanceNodeService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class TaskInstanceNodeController extends BaseController {
    @Autowired
    private TaskInstanceNodeService taskInstanceNodeService;
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @PostMapping("/taskInstanceNode/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<TaskInstanceNode, BaseParam> pageParam = new PageParam<>(baseParam, TaskInstanceNode.class);
        return R.ok().add(taskInstanceNodeService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @PostMapping("/taskInstanceNode/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(taskInstanceNodeService.list());
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @PostMapping({"/taskInstanceNode/many/{ids}", "/taskInstanceNodes/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(taskInstanceNodeService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @GetMapping("/taskInstanceNode/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(taskInstanceNodeService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:save')")
    @OperationLog("Create 物料权限")
    @PostMapping("/taskInstanceNode/save")
    public R save(@RequestBody TaskInstanceNode taskInstanceNode) {
        taskInstanceNode.setCreateTime(new Date());
        taskInstanceNode.setUpdateTime(new Date());
        if (!taskInstanceNodeService.save(taskInstanceNode)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(taskInstanceNode);
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:update')")
    @OperationLog("Update 物料权限")
    @PostMapping("/taskInstanceNode/update")
    public R update(@RequestBody TaskInstanceNode taskInstanceNode) {
        taskInstanceNode.setUpdateTime(new Date());
        if (!taskInstanceNodeService.updateById(taskInstanceNode)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(taskInstanceNode);
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:remove')")
    @OperationLog("Delete 物料权限")
    @PostMapping("/taskInstanceNode/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!taskInstanceNodeService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @PostMapping("/taskInstanceNode/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<TaskInstanceNode> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(TaskInstanceNode::getId, condition);
        }
        taskInstanceNodeService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:taskInstanceNode:list')")
    @PostMapping("/taskInstanceNode/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(taskInstanceNodeService.list(), TaskInstanceNode.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskPathTemplateController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.TaskPathTemplate;
import com.vincent.rsf.server.system.service.TaskPathTemplateService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class TaskPathTemplateController extends BaseController {
    @Autowired
    private TaskPathTemplateService taskPathTemplateService;
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @PostMapping("/taskPathTemplate/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<TaskPathTemplate, BaseParam> pageParam = new PageParam<>(baseParam, TaskPathTemplate.class);
        return R.ok().add(taskPathTemplateService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @PostMapping("/taskPathTemplate/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(taskPathTemplateService.list());
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @PostMapping({"/taskPathTemplate/many/{ids}", "/taskPathTemplates/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(taskPathTemplateService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @GetMapping("/taskPathTemplate/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(taskPathTemplateService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:save')")
    @OperationLog("Create 物料权限")
    @PostMapping("/taskPathTemplate/save")
    public R save(@RequestBody TaskPathTemplate taskPathTemplate) {
        taskPathTemplate.setCreateBy(getLoginUserId());
        taskPathTemplate.setCreateTime(new Date());
        taskPathTemplate.setUpdateBy(getLoginUserId());
        taskPathTemplate.setUpdateTime(new Date());
        if (!taskPathTemplateService.save(taskPathTemplate)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(taskPathTemplate);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:update')")
    @OperationLog("Update 物料权限")
    @PostMapping("/taskPathTemplate/update")
    public R update(@RequestBody TaskPathTemplate taskPathTemplate) {
        taskPathTemplate.setUpdateBy(getLoginUserId());
        taskPathTemplate.setUpdateTime(new Date());
        if (!taskPathTemplateService.updateById(taskPathTemplate)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(taskPathTemplate);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:remove')")
    @OperationLog("Delete 物料权限")
    @PostMapping("/taskPathTemplate/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!taskPathTemplateService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @PostMapping("/taskPathTemplate/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<TaskPathTemplate> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(TaskPathTemplate::getId, condition);
        }
        taskPathTemplateService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplate:list')")
    @PostMapping("/taskPathTemplate/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(taskPathTemplateService.list(), TaskPathTemplate.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/TaskPathTemplateNodeController.java
New file
@@ -0,0 +1,110 @@
package com.vincent.rsf.server.system.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.R;
import com.vincent.rsf.server.common.utils.ExcelUtil;
import com.vincent.rsf.server.common.annotation.OperationLog;
import com.vincent.rsf.server.common.domain.BaseParam;
import com.vincent.rsf.server.common.domain.KeyValVo;
import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.TaskPathTemplateNode;
import com.vincent.rsf.server.system.service.TaskPathTemplateNodeService;
import com.vincent.rsf.server.system.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
@RestController
public class TaskPathTemplateNodeController extends BaseController {
    @Autowired
    private TaskPathTemplateNodeService taskPathTemplateNodeService;
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @PostMapping("/taskPathTemplateNode/page")
    public R page(@RequestBody Map<String, Object> map) {
        BaseParam baseParam = buildParam(map, BaseParam.class);
        PageParam<TaskPathTemplateNode, BaseParam> pageParam = new PageParam<>(baseParam, TaskPathTemplateNode.class);
        return R.ok().add(taskPathTemplateNodeService.page(pageParam, pageParam.buildWrapper(true)));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @PostMapping("/taskPathTemplateNode/list")
    public R list(@RequestBody Map<String, Object> map) {
        return R.ok().add(taskPathTemplateNodeService.list());
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @PostMapping({"/taskPathTemplateNode/many/{ids}", "/taskPathTemplateNodes/many/{ids}"})
    public R many(@PathVariable Long[] ids) {
        return R.ok().add(taskPathTemplateNodeService.listByIds(Arrays.asList(ids)));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @GetMapping("/taskPathTemplateNode/{id}")
    public R get(@PathVariable("id") Long id) {
        return R.ok().add(taskPathTemplateNodeService.getById(id));
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:save')")
    @OperationLog("Create 物料权限")
    @PostMapping("/taskPathTemplateNode/save")
    public R save(@RequestBody TaskPathTemplateNode taskPathTemplateNode) {
        taskPathTemplateNode.setCreateBy(getLoginUserId());
        taskPathTemplateNode.setCreateTime(new Date());
        taskPathTemplateNode.setUpdateBy(getLoginUserId());
        taskPathTemplateNode.setUpdateTime(new Date());
        if (!taskPathTemplateNodeService.save(taskPathTemplateNode)) {
            return R.error("Save Fail");
        }
        return R.ok("Save Success").add(taskPathTemplateNode);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:update')")
    @OperationLog("Update 物料权限")
    @PostMapping("/taskPathTemplateNode/update")
    public R update(@RequestBody TaskPathTemplateNode taskPathTemplateNode) {
        taskPathTemplateNode.setUpdateBy(getLoginUserId());
        taskPathTemplateNode.setUpdateTime(new Date());
        if (!taskPathTemplateNodeService.updateById(taskPathTemplateNode)) {
            return R.error("Update Fail");
        }
        return R.ok("Update Success").add(taskPathTemplateNode);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:remove')")
    @OperationLog("Delete 物料权限")
    @PostMapping("/taskPathTemplateNode/remove/{ids}")
    public R remove(@PathVariable Long[] ids) {
        if (!taskPathTemplateNodeService.removeByIds(Arrays.asList(ids))) {
            return R.error("Delete Fail");
        }
        return R.ok("Delete Success").add(ids);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @PostMapping("/taskPathTemplateNode/query")
    public R query(@RequestParam(required = false) String condition) {
        List<KeyValVo> vos = new ArrayList<>();
        LambdaQueryWrapper<TaskPathTemplateNode> wrapper = new LambdaQueryWrapper<>();
        if (!Cools.isEmpty(condition)) {
            wrapper.like(TaskPathTemplateNode::getId, condition);
        }
        taskPathTemplateNodeService.page(new Page<>(1, 30), wrapper).getRecords().forEach(
                item -> vos.add(new KeyValVo(item.getId(), item.getId()))
        );
        return R.ok().add(vos);
    }
    @PreAuthorize("hasAuthority('system:taskPathTemplateNode:list')")
    @PostMapping("/taskPathTemplateNode/export")
    public void export(@RequestBody Map<String, Object> map, HttpServletResponse response) throws Exception {
        ExcelUtil.build(ExcelUtil.create(taskPathTemplateNodeService.list(), TaskPathTemplateNode.class), response);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowInstance.java
New file
@@ -0,0 +1,297 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_flow_instance")
public class FlowInstance implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 流程实例编号
     */
    @ApiModelProperty(value= "流程实例编号")
    private String flowInstanceNo;
    /**
     * 关联task_instance.id
     */
    @ApiModelProperty(value= "关联task_instance.id")
    private Long taskId;
    /**
     * 任务编号
     */
    @ApiModelProperty(value= "任务编号")
    private String taskNo;
    /**
     * 关联task_instance_node.id
     */
    @ApiModelProperty(value= "关联task_instance_node.id")
    private Long nodeInstanceId;
    /**
     * 节点编码
     */
    @ApiModelProperty(value= "节点编码")
    private String nodeCode;
    /**
     * 使用的流程模板ID
     */
    @ApiModelProperty(value= "使用的流程模板ID")
    private Long flowTemplateId;
    /**
     * 流程模板编码
     */
    @ApiModelProperty(value= "流程模板编码")
    private String flowTemplateCode;
    /**
     * 模板版本
     */
    @ApiModelProperty(value= "模板版本")
    private Integer templateVersion;
    /**
     * 状态:0-未开始 1-执行中 2-成功 3-失败 4-取消 5-超时
     */
    @ApiModelProperty(value= "状态:0-未开始 1-执行中 2-成功 3-失败 4-取消 5-超时")
    private Short status;
    /**
     * 当前步骤编码
     */
    @ApiModelProperty(value= "当前步骤编码")
    private String currentStepCode;
    /**
     * 当前步骤顺序
     */
    @ApiModelProperty(value= "当前步骤顺序")
    private Integer currentStepOrder;
    /**
     * 执行入参
     */
    @ApiModelProperty(value= "执行入参")
    private String executeParams;
    /**
     * 执行结果
     */
    @ApiModelProperty(value= "执行结果")
    private String executeResult;
    /**
     * 错误码
     */
    @ApiModelProperty(value= "错误码")
    private String errorCode;
    /**
     * 错误信息
     */
    @ApiModelProperty(value= "错误信息")
    private String errorMessage;
    /**
     * 开始时间
     */
    @ApiModelProperty(value= "开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    /**
     * 结束时间
     */
    @ApiModelProperty(value= "结束时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    /**
     * 超时时间
     */
    @ApiModelProperty(value= "超时时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date timeoutAt;
    /**
     * 执行耗时(秒)
     */
    @ApiModelProperty(value= "执行耗时(秒)")
    private Integer durationSeconds;
    /**
     * 已重试次数
     */
    @ApiModelProperty(value= "已重试次数")
    private Integer retryTimes;
    /**
     * 最后重试时间
     */
    @ApiModelProperty(value= "最后重试时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date lastRetryTime;
    /**
     * 流程上下文数据
     */
    @ApiModelProperty(value= "流程上下文数据")
    private String contextData;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public FlowInstance() {}
    public FlowInstance(String flowInstanceNo,Long taskId,String taskNo,Long nodeInstanceId,String nodeCode,Long flowTemplateId,String flowTemplateCode,Integer templateVersion,Short status,String currentStepCode,Integer currentStepOrder,String executeParams,String executeResult,String errorCode,String errorMessage,Date startTime,Date endTime,Date timeoutAt,Integer durationSeconds,Integer retryTimes,Date lastRetryTime,String contextData,Date createTime,Date updateTime) {
        this.flowInstanceNo = flowInstanceNo;
        this.taskId = taskId;
        this.taskNo = taskNo;
        this.nodeInstanceId = nodeInstanceId;
        this.nodeCode = nodeCode;
        this.flowTemplateId = flowTemplateId;
        this.flowTemplateCode = flowTemplateCode;
        this.templateVersion = templateVersion;
        this.status = status;
        this.currentStepCode = currentStepCode;
        this.currentStepOrder = currentStepOrder;
        this.executeParams = executeParams;
        this.executeResult = executeResult;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.startTime = startTime;
        this.endTime = endTime;
        this.timeoutAt = timeoutAt;
        this.durationSeconds = durationSeconds;
        this.retryTimes = retryTimes;
        this.lastRetryTime = lastRetryTime;
        this.contextData = contextData;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    FlowInstance flowInstance = new FlowInstance(
//            null,    // 流程实例编号[非空]
//            null,    // 关联task_instance.id[非空]
//            null,    // 任务编号[非空]
//            null,    // 关联task_instance_node.id[非空]
//            null,    // 节点编码[非空]
//            null,    // 使用的流程模板ID[非空]
//            null,    // 流程模板编码[非空]
//            null,    // 模板版本[非空]
//            null,    // 状态:0-未开始 1-执行中 2-成功 3-失败 4-取消 5-超时[非空]
//            null,    // 当前步骤编码
//            null,    // 当前步骤顺序
//            null,    // 执行入参
//            null,    // 执行结果
//            null,    // 错误码
//            null,    // 错误信息
//            null,    // 开始时间
//            null,    // 结束时间
//            null,    // 超时时间
//            null,    // 执行耗时(秒)
//            null,    // 已重试次数[非空]
//            null,    // 最后重试时间
//            null,    // 流程上下文数据
//            null,    //
//            null    //
//    );
    public String getStartTime$(){
        if (Cools.isEmpty(this.startTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.startTime);
    }
    public String getEndTime$(){
        if (Cools.isEmpty(this.endTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.endTime);
    }
    public String getTimeoutAt$(){
        if (Cools.isEmpty(this.timeoutAt)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.timeoutAt);
    }
    public String getLastRetryTime$(){
        if (Cools.isEmpty(this.lastRetryTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lastRetryTime);
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepInstance.java
New file
@@ -0,0 +1,237 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_flow_step_instance")
public class FlowStepInstance implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 关联flow_instance.id
     */
    @ApiModelProperty(value= "关联flow_instance.id")
    private Long flowInstanceId;
    /**
     * 流程实例编号
     */
    @ApiModelProperty(value= "流程实例编号")
    private String flowInstanceNo;
    /**
     * 步骤顺序
     */
    @ApiModelProperty(value= "步骤顺序")
    private Integer stepOrder;
    /**
     * 步骤编码
     */
    @ApiModelProperty(value= "步骤编码")
    private String stepCode;
    /**
     * 步骤名称
     */
    @ApiModelProperty(value= "步骤名称")
    private String stepName;
    /**
     * 步骤类型
     */
    @ApiModelProperty(value= "步骤类型")
    private String stepType;
    /**
     * 步骤模板ID
     */
    @ApiModelProperty(value= "步骤模板ID")
    private Long stepTemplateId;
    /**
     * 状态:0-待执行 1-执行中 2-成功 3-失败 4-跳过 5-超时
     */
    @ApiModelProperty(value= "状态:0-待执行 1-执行中 2-成功 3-失败 4-跳过 5-超时")
    private Short status;
    /**
     * 执行结果
     */
    @ApiModelProperty(value= "执行结果")
    private String executeResult;
    /**
     * 错误码
     */
    @ApiModelProperty(value= "错误码")
    private String errorCode;
    /**
     * 错误信息
     */
    @ApiModelProperty(value= "错误信息")
    private String errorMessage;
    /**
     * 开始时间
     */
    @ApiModelProperty(value= "开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    /**
     * 结束时间
     */
    @ApiModelProperty(value= "结束时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    /**
     * 执行耗时(秒)
     */
    @ApiModelProperty(value= "执行耗时(秒)")
    private Integer durationSeconds;
    /**
     * 输入数据快照
     */
    @ApiModelProperty(value= "输入数据快照")
    private String inputData;
    /**
     * 输出数据快照
     */
    @ApiModelProperty(value= "输出数据快照")
    private String outputData;
    /**
     * 步骤重试次数
     */
    @ApiModelProperty(value= "步骤重试次数")
    private Integer retryTimes;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public FlowStepInstance() {}
    public FlowStepInstance(Long flowInstanceId,String flowInstanceNo,Integer stepOrder,String stepCode,String stepName,String stepType,Long stepTemplateId,Short status,String executeResult,String errorCode,String errorMessage,Date startTime,Date endTime,Integer durationSeconds,String inputData,String outputData,Integer retryTimes,Date createTime,Date updateTime) {
        this.flowInstanceId = flowInstanceId;
        this.flowInstanceNo = flowInstanceNo;
        this.stepOrder = stepOrder;
        this.stepCode = stepCode;
        this.stepName = stepName;
        this.stepType = stepType;
        this.stepTemplateId = stepTemplateId;
        this.status = status;
        this.executeResult = executeResult;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.startTime = startTime;
        this.endTime = endTime;
        this.durationSeconds = durationSeconds;
        this.inputData = inputData;
        this.outputData = outputData;
        this.retryTimes = retryTimes;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    FlowStepInstance flowStepInstance = new FlowStepInstance(
//            null,    // 关联flow_instance.id[非空]
//            null,    // 流程实例编号[非空]
//            null,    // 步骤顺序[非空]
//            null,    // 步骤编码[非空]
//            null,    // 步骤名称[非空]
//            null,    // 步骤类型[非空]
//            null,    // 步骤模板ID[非空]
//            null,    // 状态:0-待执行 1-执行中 2-成功 3-失败 4-跳过 5-超时[非空]
//            null,    // 执行结果
//            null,    // 错误码
//            null,    // 错误信息
//            null,    // 开始时间
//            null,    // 结束时间
//            null,    // 执行耗时(秒)
//            null,    // 输入数据快照
//            null,    // 输出数据快照
//            null,    // 步骤重试次数[非空]
//            null,    //
//            null    //
//    );
    public String getStartTime$(){
        if (Cools.isEmpty(this.startTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.startTime);
    }
    public String getEndTime$(){
        if (Cools.isEmpty(this.endTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.endTime);
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepLog.java
New file
@@ -0,0 +1,125 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_flow_step_log")
public class FlowStepLog implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 流程实例ID
     */
    @ApiModelProperty(value= "流程实例ID")
    private Long flowInstanceId;
    /**
     * 步骤实例ID
     */
    @ApiModelProperty(value= "步骤实例ID")
    private Long stepInstanceId;
    /**
     * 日志类型:REQUEST, RESPONSE, ERROR, DEBUG
     */
    @ApiModelProperty(value= "日志类型:REQUEST, RESPONSE, ERROR, DEBUG")
    private String logType;
    /**
     * 日志级别:INFO, WARN, ERROR
     */
    @ApiModelProperty(value= "日志级别:INFO, WARN, ERROR")
    private String logLevel;
    /**
     * 日志内容
     */
    @ApiModelProperty(value= "日志内容")
    private String logContent;
    /**
     * 请求数据
     */
    @ApiModelProperty(value= "请求数据")
    private String requestData;
    /**
     * 响应数据
     */
    @ApiModelProperty(value= "响应数据")
    private String responseData;
    /**
     * 精确到毫秒
     */
    @ApiModelProperty(value= "精确到毫秒")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    public FlowStepLog() {}
    public FlowStepLog(Long flowInstanceId,Long stepInstanceId,String logType,String logLevel,String logContent,String requestData,String responseData,Date createTime) {
        this.flowInstanceId = flowInstanceId;
        this.stepInstanceId = stepInstanceId;
        this.logType = logType;
        this.logLevel = logLevel;
        this.logContent = logContent;
        this.requestData = requestData;
        this.responseData = responseData;
        this.createTime = createTime;
    }
//    FlowStepLog flowStepLog = new FlowStepLog(
//            null,    // 流程实例ID[非空]
//            null,    // 步骤实例ID[非空]
//            null,    // 日志类型:REQUEST, RESPONSE, ERROR, DEBUG[非空]
//            null,    // 日志级别:INFO, WARN, ERROR[非空]
//            null,    // 日志内容
//            null,    // 请求数据
//            null,    // 响应数据
//            null    // 精确到毫秒
//    );
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/FlowStepTemplate.java
New file
@@ -0,0 +1,197 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_flow_step_template")
public class FlowStepTemplate implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 关联flow_template.id
     */
    @ApiModelProperty(value= "关联flow_template.id")
    private Long flowId;
    /**
     * 流程编码
     */
    @ApiModelProperty(value= "流程编码")
    private String flowCode;
    /**
     * 步骤顺序
     */
    @ApiModelProperty(value= "步骤顺序")
    private Integer stepOrder;
    /**
     * 步骤编码
     */
    @ApiModelProperty(value= "步骤编码")
    private String stepCode;
    /**
     * 步骤名称
     */
    @ApiModelProperty(value= "步骤名称")
    private String stepName;
    /**
     * 步骤类型:REQUEST-请求, RESPONSE-响应, VALIDATE-校验, TRANSFORM-转换
     */
    @ApiModelProperty(value= "步骤类型:REQUEST-请求, RESPONSE-响应, VALIDATE-校验, TRANSFORM-转换")
    private String stepType;
    /**
     * 动作类型:HTTP_CALL, RPC_CALL, MQ_SEND, DB_OPERATION
     */
    @ApiModelProperty(value= "动作类型:HTTP_CALL, RPC_CALL, MQ_SEND, DB_OPERATION")
    private String actionType;
    /**
     * 动作配置(JSON)
     */
    @ApiModelProperty(value= "动作配置(JSON)")
    private String actionConfig;
    /**
     * 输入参数映射规则
     */
    @ApiModelProperty(value= "输入参数映射规则")
    private String inputMapping;
    /**
     * 输出参数映射规则
     */
    @ApiModelProperty(value= "输出参数映射规则")
    private String outputMapping;
    /**
     * 执行条件表达式
     */
    @ApiModelProperty(value= "执行条件表达式")
    private String conditionExpression;
    /**
     * 失败时是否跳过后续步骤
     */
    @ApiModelProperty(value= "失败时是否跳过后续步骤")
    private Short skipOnFail;
    /**
     * 是否启用重试
     */
    @ApiModelProperty(value= "是否启用重试")
    private Short retryEnabled;
    /**
     * 重试配置
     */
    @ApiModelProperty(value= "重试配置")
    private String retryConfig;
    /**
     * 步骤超时时间
     */
    @ApiModelProperty(value= "步骤超时时间")
    private Integer timeoutSeconds;
    @ApiModelProperty(value= "")
    private Long createBy;
    @ApiModelProperty(value= "")
    private Long updateBy;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public FlowStepTemplate() {}
    public FlowStepTemplate(Long flowId,String flowCode,Integer stepOrder,String stepCode,String stepName,String stepType,String actionType,String actionConfig,String inputMapping,String outputMapping,String conditionExpression,Short skipOnFail,Short retryEnabled,String retryConfig,Integer timeoutSeconds,Long createBy,Long updateBy,Date createTime,Date updateTime) {
        this.flowId = flowId;
        this.flowCode = flowCode;
        this.stepOrder = stepOrder;
        this.stepCode = stepCode;
        this.stepName = stepName;
        this.stepType = stepType;
        this.actionType = actionType;
        this.actionConfig = actionConfig;
        this.inputMapping = inputMapping;
        this.outputMapping = outputMapping;
        this.conditionExpression = conditionExpression;
        this.skipOnFail = skipOnFail;
        this.retryEnabled = retryEnabled;
        this.retryConfig = retryConfig;
        this.timeoutSeconds = timeoutSeconds;
        this.createBy = createBy;
        this.updateBy = updateBy;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    FlowStepTemplate flowStepTemplate = new FlowStepTemplate(
//            null,    // 关联flow_template.id[非空]
//            null,    // 流程编码[非空]
//            null,    // 步骤顺序[非空]
//            null,    // 步骤编码[非空]
//            null,    // 步骤名称[非空]
//            null,    // 步骤类型:REQUEST-请求, RESPONSE-响应, VALIDATE-校验, TRANSFORM-转换[非空]
//            null,    // 动作类型:HTTP_CALL, RPC_CALL, MQ_SEND, DB_OPERATION[非空]
//            null,    // 动作配置(JSON)[非空]
//            null,    // 输入参数映射规则
//            null,    // 输出参数映射规则
//            null,    // 执行条件表达式
//            null,    // 失败时是否跳过后续步骤
//            null,    // 是否启用重试
//            null,    // 重试配置
//            null,    // 步骤超时时间
//            null,    //
//            null,    //
//            null,    //
//            null    //
//    );
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/SubsystemFlowTemplate.java
New file
@@ -0,0 +1,215 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_subsystem_flow_template")
public class SubsystemFlowTemplate implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 流程编码
     */
    @ApiModelProperty(value= "流程编码")
    private String flowCode;
    /**
     * 流程名称
     */
    @ApiModelProperty(value= "流程名称")
    private String flowName;
    /**
     * 子系统编码
     */
    @ApiModelProperty(value= "子系统编码")
    private String systemCode;
    /**
     * 子系统名称
     */
    @ApiModelProperty(value= "子系统名称")
    private String systemName;
    /**
     * 适用的节点类型
     */
    @ApiModelProperty(value= "适用的节点类型")
    private String nodeType;
    @ApiModelProperty(value= "")
    private Integer version;
    /**
     * 是否当前生效
     */
    @ApiModelProperty(value= "是否当前生效")
    private Short isCurrent;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date effectiveTime;
    /**
     * 超时策略:FAIL-失败, RETRY-重试, SKIP-跳过
     */
    @ApiModelProperty(value= "超时策略:FAIL-失败, RETRY-重试, SKIP-跳过")
    private String timeoutStrategy;
    /**
     * 整体超时时间(秒)
     */
    @ApiModelProperty(value= "整体超时时间(秒)")
    private Integer timeoutSeconds;
    /**
     * 最大重试次数
     */
    @ApiModelProperty(value= "最大重试次数")
    private Integer maxRetryTimes;
    /**
     * 是否需要通知
     */
    @ApiModelProperty(value= "是否需要通知")
    private Short needNotify;
    /**
     * 通知模板配置
     */
    @ApiModelProperty(value= "通知模板配置")
    private String notifyTemplate;
    /**
     * 状态 0-禁用 1-启用
     */
    @ApiModelProperty(value= "状态 0-禁用 1-启用")
    private Short status;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String remark;
    @ApiModelProperty(value= "")
    private Long createBy;
    @ApiModelProperty(value= "")
    private Long updateBy;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public SubsystemFlowTemplate() {}
    public SubsystemFlowTemplate(String flowCode,String flowName,String systemCode,String systemName,String nodeType,Integer version,Short isCurrent,Date effectiveTime,String timeoutStrategy,Integer timeoutSeconds,Integer maxRetryTimes,Short needNotify,String notifyTemplate,Short status,String remark,Long createBy,Long updateBy,Date createTime,Date updateTime) {
        this.flowCode = flowCode;
        this.flowName = flowName;
        this.systemCode = systemCode;
        this.systemName = systemName;
        this.nodeType = nodeType;
        this.version = version;
        this.isCurrent = isCurrent;
        this.effectiveTime = effectiveTime;
        this.timeoutStrategy = timeoutStrategy;
        this.timeoutSeconds = timeoutSeconds;
        this.maxRetryTimes = maxRetryTimes;
        this.needNotify = needNotify;
        this.notifyTemplate = notifyTemplate;
        this.status = status;
        this.remark = remark;
        this.createBy = createBy;
        this.updateBy = updateBy;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    SubsystemFlowTemplate subsystemFlowTemplate = new SubsystemFlowTemplate(
//            null,    // 流程编码[非空]
//            null,    // 流程名称[非空]
//            null,    // 子系统编码[非空]
//            null,    // 子系统名称
//            null,    // 适用的节点类型[非空]
//            null,    // [非空]
//            null,    // 是否当前生效[非空]
//            null,    // [非空]
//            null,    // 超时策略:FAIL-失败, RETRY-重试, SKIP-跳过
//            null,    // 整体超时时间(秒)
//            null,    // 最大重试次数
//            null,    // 是否需要通知
//            null,    // 通知模板配置
//            null,    // 状态 0-禁用 1-启用[非空]
//            null,    // 备注
//            null,    //
//            null,    //
//            null,    //
//            null    //
//    );
    public String getEffectiveTime$(){
        if (Cools.isEmpty(this.effectiveTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.effectiveTime);
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskInstance.java
New file
@@ -0,0 +1,379 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_task_instance")
public class TaskInstance implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 任务编号,业务唯一
     */
    @ApiModelProperty(value= "任务编号,业务唯一")
    private String taskNo;
    /**
     * 业务单号,外部系统传入
     */
    @ApiModelProperty(value= "业务单号,外部系统传入")
    private String bizNo;
    /**
     * 业务类型
     */
    @ApiModelProperty(value= "业务类型")
    private String bizType;
    /**
     * 使用的模板ID
     */
    @ApiModelProperty(value= "使用的模板ID")
    private Long templateId;
    /**
     * 模板编码
     */
    @ApiModelProperty(value= "模板编码")
    private String templateCode;
    /**
     * 使用的模板版本
     */
    @ApiModelProperty(value= "使用的模板版本")
    private Integer templateVersion;
    /**
     * 起点信息(JSON)
     */
    @ApiModelProperty(value= "起点信息(JSON)")
    private String sourceInfo;
    /**
     * 终点信息(JSON)
     */
    @ApiModelProperty(value= "终点信息(JSON)")
    private String targetInfo;
    /**
     * 起点编码
     */
    @ApiModelProperty(value= "起点编码")
    private String sourceCode;
    /**
     * 终点编码
     */
    @ApiModelProperty(value= "终点编码")
    private String targetCode;
    /**
     * 规划路径(JSON数组)
     */
    @ApiModelProperty(value= "规划路径(JSON数组)")
    private String plannedPath;
    /**
     * 实际执行路径(JSON数组)
     */
    @ApiModelProperty(value= "实际执行路径(JSON数组)")
    private String actualPath;
    /**
     * 优先级
     */
    @ApiModelProperty(value= "优先级")
    private Short priority;
    /**
     * 整体超时时间
     */
    @ApiModelProperty(value= "整体超时时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date timeoutAt;
    /**
     * 状态:0-已创建 1-执行中 2-已完成 3-已失败 4-已取消 5-已超时
     */
    @ApiModelProperty(value= "状态:0-已创建 1-执行中 2-已完成 3-已失败 4-已取消 5-已超时")
    private Short status;
    /**
     * 当前所在节点编码
     */
    @ApiModelProperty(value= "当前所在节点编码")
    private String currentNodeCode;
    /**
     * 当前所在节点名称
     */
    @ApiModelProperty(value= "当前所在节点名称")
    private String currentNodeName;
    /**
     * 总节点数
     */
    @ApiModelProperty(value= "总节点数")
    private Integer totalNodes;
    /**
     * 已完成节点数
     */
    @ApiModelProperty(value= "已完成节点数")
    private Integer completedNodes;
    /**
     * 进度百分比
     */
    @ApiModelProperty(value= "进度百分比")
    private Double progressRate;
    /**
     * 预估耗时(分钟)
     */
    @ApiModelProperty(value= "预估耗时(分钟)")
    private Integer estimatedDurationMinutes;
    /**
     * 实际耗时(分钟)
     */
    @ApiModelProperty(value= "实际耗时(分钟)")
    private Integer actualDurationMinutes;
    /**
     * 开始时间
     */
    @ApiModelProperty(value= "开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    /**
     * 结束时间
     */
    @ApiModelProperty(value= "结束时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    /**
     * 结果编码:SUCCESS, FAILED, PARTIAL_SUCCESS等
     */
    @ApiModelProperty(value= "结果编码:SUCCESS, FAILED, PARTIAL_SUCCESS等")
    private String resultCode;
    /**
     * 结果描述
     */
    @ApiModelProperty(value= "结果描述")
    private String resultMessage;
    /**
     * 最终结果数据
     */
    @ApiModelProperty(value= "最终结果数据")
    private String resultData;
    /**
     * 已重试次数
     */
    @ApiModelProperty(value= "已重试次数")
    private Integer retryTimes;
    /**
     * 最后重试时间
     */
    @ApiModelProperty(value= "最后重试时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date lastRetryTime;
    /**
     * 扩展参数
     */
    @ApiModelProperty(value= "扩展参数")
    private String extParams;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String remark;
    @ApiModelProperty(value= "")
    private Long createBy;
    @ApiModelProperty(value= "")
    private Long updateBy;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public TaskInstance() {}
    public TaskInstance(String taskNo,String bizNo,String bizType,Long templateId,String templateCode,Integer templateVersion,String sourceInfo,String targetInfo,String sourceCode,String targetCode,String plannedPath,String actualPath,Short priority,Date timeoutAt,Short status,String currentNodeCode,String currentNodeName,Integer totalNodes,Integer completedNodes,Double progressRate,Integer estimatedDurationMinutes,Integer actualDurationMinutes,Date startTime,Date endTime,String resultCode,String resultMessage,String resultData,Integer retryTimes,Date lastRetryTime,String extParams,String remark,Long createBy,Long updateBy,Date createTime,Date updateTime) {
        this.taskNo = taskNo;
        this.bizNo = bizNo;
        this.bizType = bizType;
        this.templateId = templateId;
        this.templateCode = templateCode;
        this.templateVersion = templateVersion;
        this.sourceInfo = sourceInfo;
        this.targetInfo = targetInfo;
        this.sourceCode = sourceCode;
        this.targetCode = targetCode;
        this.plannedPath = plannedPath;
        this.actualPath = actualPath;
        this.priority = priority;
        this.timeoutAt = timeoutAt;
        this.status = status;
        this.currentNodeCode = currentNodeCode;
        this.currentNodeName = currentNodeName;
        this.totalNodes = totalNodes;
        this.completedNodes = completedNodes;
        this.progressRate = progressRate;
        this.estimatedDurationMinutes = estimatedDurationMinutes;
        this.actualDurationMinutes = actualDurationMinutes;
        this.startTime = startTime;
        this.endTime = endTime;
        this.resultCode = resultCode;
        this.resultMessage = resultMessage;
        this.resultData = resultData;
        this.retryTimes = retryTimes;
        this.lastRetryTime = lastRetryTime;
        this.extParams = extParams;
        this.remark = remark;
        this.createBy = createBy;
        this.updateBy = updateBy;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    TaskInstance taskInstance = new TaskInstance(
//            null,    // 任务编号,业务唯一[非空]
//            null,    // 业务单号,外部系统传入
//            null,    // 业务类型[非空]
//            null,    // 使用的模板ID[非空]
//            null,    // 模板编码[非空]
//            null,    // 使用的模板版本[非空]
//            null,    // 起点信息(JSON)[非空]
//            null,    // 终点信息(JSON)[非空]
//            null,    // 起点编码[非空]
//            null,    // 终点编码[非空]
//            null,    // 规划路径(JSON数组)
//            null,    // 实际执行路径(JSON数组)
//            null,    // 优先级[非空]
//            null,    // 整体超时时间
//            null,    // 状态:0-已创建 1-执行中 2-已完成 3-已失败 4-已取消 5-已超时[非空]
//            null,    // 当前所在节点编码
//            null,    // 当前所在节点名称
//            null,    // 总节点数[非空]
//            null,    // 已完成节点数[非空]
//            null,    // 进度百分比
//            null,    // 预估耗时(分钟)
//            null,    // 实际耗时(分钟)
//            null,    // 开始时间
//            null,    // 结束时间
//            null,    // 结果编码:SUCCESS, FAILED, PARTIAL_SUCCESS等
//            null,    // 结果描述
//            null,    // 最终结果数据
//            null,    // 已重试次数[非空]
//            null,    // 最后重试时间
//            null,    // 扩展参数
//            null,    // 备注
//            null,    //
//            null,    //
//            null,    //
//            null    //
//    );
    public String getTimeoutAt$(){
        if (Cools.isEmpty(this.timeoutAt)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.timeoutAt);
    }
    public String getStartTime$(){
        if (Cools.isEmpty(this.startTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.startTime);
    }
    public String getEndTime$(){
        if (Cools.isEmpty(this.endTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.endTime);
    }
    public String getLastRetryTime$(){
        if (Cools.isEmpty(this.lastRetryTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.lastRetryTime);
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskInstanceNode.java
New file
@@ -0,0 +1,289 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_task_instance_node")
public class TaskInstanceNode implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 关联task_instance.id
     */
    @ApiModelProperty(value= "关联task_instance.id")
    private Long taskId;
    /**
     * 任务编号
     */
    @ApiModelProperty(value= "任务编号")
    private String taskNo;
    /**
     * 节点顺序
     */
    @ApiModelProperty(value= "节点顺序")
    private Integer nodeOrder;
    /**
     * 节点编码
     */
    @ApiModelProperty(value= "节点编码")
    private String nodeCode;
    /**
     * 节点名称
     */
    @ApiModelProperty(value= "节点名称")
    private String nodeName;
    /**
     * 节点类型
     */
    @ApiModelProperty(value= "节点类型")
    private String nodeType;
    /**
     * 子系统编码
     */
    @ApiModelProperty(value= "子系统编码")
    private String systemCode;
    /**
     * 子系统名称
     */
    @ApiModelProperty(value= "子系统名称")
    private String systemName;
    /**
     * 实际执行参数
     */
    @ApiModelProperty(value= "实际执行参数")
    private String executeParams;
    /**
     * 状态:0-待执行 1-执行中 2-执行成功 3-执行失败 4-已跳过 5-已取消
     */
    @ApiModelProperty(value= "状态:0-待执行 1-执行中 2-执行成功 3-执行失败 4-已跳过 5-已取消")
    private Short status;
    /**
     * 执行结果数据
     */
    @ApiModelProperty(value= "执行结果数据")
    private String executeResult;
    /**
     * 错误码
     */
    @ApiModelProperty(value= "错误码")
    private String errorCode;
    /**
     * 错误信息
     */
    @ApiModelProperty(value= "错误信息")
    private String errorMessage;
    /**
     * 预计开始时间
     */
    @ApiModelProperty(value= "预计开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date estimatedStartTime;
    /**
     * 实际开始时间
     */
    @ApiModelProperty(value= "实际开始时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date actualStartTime;
    /**
     * 实际结束时间
     */
    @ApiModelProperty(value= "实际结束时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date actualEndTime;
    /**
     * 节点超时时间
     */
    @ApiModelProperty(value= "节点超时时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date timeoutAt;
    /**
     * 执行耗时(秒)
     */
    @ApiModelProperty(value= "执行耗时(秒)")
    private Integer durationSeconds;
    /**
     * 节点重试次数
     */
    @ApiModelProperty(value= "节点重试次数")
    private Integer retryTimes;
    /**
     * 节点最大重试次数
     */
    @ApiModelProperty(value= "节点最大重试次数")
    private Integer maxRetryTimes;
    /**
     * 依赖的前置节点列表
     */
    @ApiModelProperty(value= "依赖的前置节点列表")
    private String dependsOnNodes;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public TaskInstanceNode() {}
    public TaskInstanceNode(Long taskId,String taskNo,Integer nodeOrder,String nodeCode,String nodeName,String nodeType,String systemCode,String systemName,String executeParams,Short status,String executeResult,String errorCode,String errorMessage,Date estimatedStartTime,Date actualStartTime,Date actualEndTime,Date timeoutAt,Integer durationSeconds,Integer retryTimes,Integer maxRetryTimes,String dependsOnNodes,Date createTime,Date updateTime) {
        this.taskId = taskId;
        this.taskNo = taskNo;
        this.nodeOrder = nodeOrder;
        this.nodeCode = nodeCode;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.systemCode = systemCode;
        this.systemName = systemName;
        this.executeParams = executeParams;
        this.status = status;
        this.executeResult = executeResult;
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.estimatedStartTime = estimatedStartTime;
        this.actualStartTime = actualStartTime;
        this.actualEndTime = actualEndTime;
        this.timeoutAt = timeoutAt;
        this.durationSeconds = durationSeconds;
        this.retryTimes = retryTimes;
        this.maxRetryTimes = maxRetryTimes;
        this.dependsOnNodes = dependsOnNodes;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    TaskInstanceNode taskInstanceNode = new TaskInstanceNode(
//            null,    // 关联task_instance.id[非空]
//            null,    // 任务编号[非空]
//            null,    // 节点顺序[非空]
//            null,    // 节点编码[非空]
//            null,    // 节点名称[非空]
//            null,    // 节点类型[非空]
//            null,    // 子系统编码[非空]
//            null,    // 子系统名称
//            null,    // 实际执行参数
//            null,    // 状态:0-待执行 1-执行中 2-执行成功 3-执行失败 4-已跳过 5-已取消[非空]
//            null,    // 执行结果数据
//            null,    // 错误码
//            null,    // 错误信息
//            null,    // 预计开始时间
//            null,    // 实际开始时间
//            null,    // 实际结束时间
//            null,    // 节点超时时间
//            null,    // 执行耗时(秒)
//            null,    // 节点重试次数[非空]
//            null,    // 节点最大重试次数[非空]
//            null,    // 依赖的前置节点列表
//            null,    //
//            null    //
//    );
    public String getEstimatedStartTime$(){
        if (Cools.isEmpty(this.estimatedStartTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.estimatedStartTime);
    }
    public String getActualStartTime$(){
        if (Cools.isEmpty(this.actualStartTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.actualStartTime);
    }
    public String getActualEndTime$(){
        if (Cools.isEmpty(this.actualEndTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.actualEndTime);
    }
    public String getTimeoutAt$(){
        if (Cools.isEmpty(this.timeoutAt)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.timeoutAt);
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskPathTemplate.java
New file
@@ -0,0 +1,254 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_task_path_template")
public class TaskPathTemplate implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键ID
     */
    @ApiModelProperty(value= "主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 模板编码,唯一标识
     */
    @ApiModelProperty(value= "模板编码,唯一标识")
    private String templateCode;
    /**
     * 模板名称
     */
    @ApiModelProperty(value= "模板名称")
    private String templateName;
    /**
     * 起点类型/起点系统标识
     */
    @ApiModelProperty(value= "起点类型/起点系统标识")
    private String sourceType;
    /**
     * 终点类型/终点系统标识
     */
    @ApiModelProperty(value= "终点类型/终点系统标识")
    private String targetType;
    /**
     * 条件表达式(JSON),用于更复杂的匹配
     */
    @ApiModelProperty(value= "条件表达式(JSON),用于更复杂的匹配")
    private String conditionExpression;
    /**
     * 条件描述,人工可读
     */
    @ApiModelProperty(value= "条件描述,人工可读")
    private String conditionDesc;
    /**
     * 版本号
     */
    @ApiModelProperty(value= "版本号")
    private Integer version;
    /**
     * 是否为当前生效版本 0-否 1-是
     */
    @ApiModelProperty(value= "是否为当前生效版本 0-否 1-是")
    private Short isCurrent;
    /**
     * 生效时间
     */
    @ApiModelProperty(value= "生效时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date effectiveTime;
    /**
     * 失效时间
     */
    @ApiModelProperty(value= "失效时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date expireTime;
    /**
     * 优先级 1-10,数字越小优先级越高
     */
    @ApiModelProperty(value= "优先级 1-10,数字越小优先级越高")
    private Short priority;
    /**
     * 整体超时时间(分钟)
     */
    @ApiModelProperty(value= "整体超时时间(分钟)")
    private Integer timeoutMinutes;
    /**
     * 最大重试次数
     */
    @ApiModelProperty(value= "最大重试次数")
    private Integer maxRetryTimes;
    /**
     * 重试间隔(秒)
     */
    @ApiModelProperty(value= "重试间隔(秒)")
    private Integer retryIntervalSeconds;
    /**
     * 状态 0-禁用 1-启用
     */
    @ApiModelProperty(value= "状态 0-禁用 1-启用")
    private Short status;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String remark;
    /**
     * 创建人
     */
    @ApiModelProperty(value= "创建人")
    private Long createBy;
    /**
     * 更新人
     */
    @ApiModelProperty(value= "更新人")
    private Long updateBy;
    /**
     * 创建时间
     */
    @ApiModelProperty(value= "创建时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 更新时间
     */
    @ApiModelProperty(value= "更新时间")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public TaskPathTemplate() {}
    public TaskPathTemplate(String templateCode,String templateName,String sourceType,String targetType,String conditionExpression,String conditionDesc,Integer version,Short isCurrent,Date effectiveTime,Date expireTime,Short priority,Integer timeoutMinutes,Integer maxRetryTimes,Integer retryIntervalSeconds,Short status,String remark,Long createBy,Long updateBy,Date createTime,Date updateTime) {
        this.templateCode = templateCode;
        this.templateName = templateName;
        this.sourceType = sourceType;
        this.targetType = targetType;
        this.conditionExpression = conditionExpression;
        this.conditionDesc = conditionDesc;
        this.version = version;
        this.isCurrent = isCurrent;
        this.effectiveTime = effectiveTime;
        this.expireTime = expireTime;
        this.priority = priority;
        this.timeoutMinutes = timeoutMinutes;
        this.maxRetryTimes = maxRetryTimes;
        this.retryIntervalSeconds = retryIntervalSeconds;
        this.status = status;
        this.remark = remark;
        this.createBy = createBy;
        this.updateBy = updateBy;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    TaskPathTemplate taskPathTemplate = new TaskPathTemplate(
//            null,    // 模板编码,唯一标识[非空]
//            null,    // 模板名称[非空]
//            null,    // 起点类型/起点系统标识[非空]
//            null,    // 终点类型/终点系统标识[非空]
//            null,    // 条件表达式(JSON),用于更复杂的匹配
//            null,    // 条件描述,人工可读
//            null,    // 版本号[非空]
//            null,    // 是否为当前生效版本 0-否 1-是[非空]
//            null,    // 生效时间[非空]
//            null,    // 失效时间
//            null,    // 优先级 1-10,数字越小优先级越高[非空]
//            null,    // 整体超时时间(分钟)
//            null,    // 最大重试次数[非空]
//            null,    // 重试间隔(秒)[非空]
//            null,    // 状态 0-禁用 1-启用[非空]
//            null,    // 备注
//            null,    // 创建人
//            null,    // 更新人
//            null,    // 创建时间
//            null    // 更新时间
//    );
    public String getEffectiveTime$(){
        if (Cools.isEmpty(this.effectiveTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.effectiveTime);
    }
    public String getExpireTime$(){
        if (Cools.isEmpty(this.expireTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.expireTime);
    }
    public String getCreatedTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdatedTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public Boolean getStatusBool(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return true;
            case 0:
                return false;
            default:
                return null;
        }
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/entity/TaskPathTemplateNode.java
New file
@@ -0,0 +1,205 @@
package com.vincent.rsf.server.system.entity;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.server.system.service.UserService;
import com.vincent.rsf.server.system.entity.User;
import java.io.Serializable;
import java.util.Date;
@Data
@TableName("mission_task_path_template_node")
public class TaskPathTemplateNode implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value= "")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 关联template.id
     */
    @ApiModelProperty(value= "关联template.id")
    private Long templateId;
    /**
     * 模板编码,冗余存储便于查询
     */
    @ApiModelProperty(value= "模板编码,冗余存储便于查询")
    private String templateCode;
    /**
     * 节点顺序,从1开始
     */
    @ApiModelProperty(value= "节点顺序,从1开始")
    private Integer nodeOrder;
    /**
     * 节点编码,如:C_SYSTEM, D_SYSTEM
     */
    @ApiModelProperty(value= "节点编码,如:C_SYSTEM, D_SYSTEM")
    private String nodeCode;
    /**
     * 节点名称
     */
    @ApiModelProperty(value= "节点名称")
    private String nodeName;
    /**
     * 节点类型:EXECUTE-执行节点, CHECK-检查点, DECISION-决策点
     */
    @ApiModelProperty(value= "节点类型:EXECUTE-执行节点, CHECK-检查点, DECISION-决策点")
    private String nodeType;
    /**
     * 对应的子系统编码
     */
    @ApiModelProperty(value= "对应的子系统编码")
    private String systemCode;
    /**
     * 子系统名称
     */
    @ApiModelProperty(value= "子系统名称")
    private String systemName;
    /**
     * 节点执行参数模板(JSON)
     */
    @ApiModelProperty(value= "节点执行参数模板(JSON)")
    private String executeParams;
    /**
     * 期望的结果数据格式(JSON Schema)
     */
    @ApiModelProperty(value= "期望的结果数据格式(JSON Schema)")
    private String resultSchema;
    /**
     * 节点超时时间(分钟),为空则使用模板的
     */
    @ApiModelProperty(value= "节点超时时间(分钟),为空则使用模板的")
    private Integer timeoutMinutes;
    /**
     * 是否必须节点 0-可选 1-必须
     */
    @ApiModelProperty(value= "是否必须节点 0-可选 1-必须")
    private Short mandatory;
    /**
     * 是否可并行执行 0-否 1-是
     */
    @ApiModelProperty(value= "是否可并行执行 0-否 1-是")
    private Short parallelExecutable;
    /**
     * 执行前置条件
     */
    @ApiModelProperty(value= "执行前置条件")
    private String preCondition;
    /**
     * 执行后置条件
     */
    @ApiModelProperty(value= "执行后置条件")
    private String postCondition;
    /**
     * 下一节点路由规则
     */
    @ApiModelProperty(value= "下一节点路由规则")
    private String nextNodeRules;
    @ApiModelProperty(value= "")
    private Long createBy;
    @ApiModelProperty(value= "")
    private Long updateBy;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value= "")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    public TaskPathTemplateNode() {}
    public TaskPathTemplateNode(Long templateId,String templateCode,Integer nodeOrder,String nodeCode,String nodeName,String nodeType,String systemCode,String systemName,String executeParams,String resultSchema,Integer timeoutMinutes,Short mandatory,Short parallelExecutable,String preCondition,String postCondition,String nextNodeRules,Long createBy,Long updateBy,Date createTime,Date updateTime) {
        this.templateId = templateId;
        this.templateCode = templateCode;
        this.nodeOrder = nodeOrder;
        this.nodeCode = nodeCode;
        this.nodeName = nodeName;
        this.nodeType = nodeType;
        this.systemCode = systemCode;
        this.systemName = systemName;
        this.executeParams = executeParams;
        this.resultSchema = resultSchema;
        this.timeoutMinutes = timeoutMinutes;
        this.mandatory = mandatory;
        this.parallelExecutable = parallelExecutable;
        this.preCondition = preCondition;
        this.postCondition = postCondition;
        this.nextNodeRules = nextNodeRules;
        this.createBy = createBy;
        this.updateBy = updateBy;
        this.createTime = createTime;
        this.updateTime = updateTime;
    }
//    TaskPathTemplateNode taskPathTemplateNode = new TaskPathTemplateNode(
//            null,    // 关联template.id[非空]
//            null,    // 模板编码,冗余存储便于查询[非空]
//            null,    // 节点顺序,从1开始[非空]
//            null,    // 节点编码,如:C_SYSTEM, D_SYSTEM[非空]
//            null,    // 节点名称[非空]
//            null,    // 节点类型:EXECUTE-执行节点, CHECK-检查点, DECISION-决策点[非空]
//            null,    // 对应的子系统编码[非空]
//            null,    // 子系统名称
//            null,    // 节点执行参数模板(JSON)
//            null,    // 期望的结果数据格式(JSON Schema)
//            null,    // 节点超时时间(分钟),为空则使用模板的
//            null,    // 是否必须节点 0-可选 1-必须[非空]
//            null,    // 是否可并行执行 0-否 1-是
//            null,    // 执行前置条件
//            null,    // 执行后置条件
//            null,    // 下一节点路由规则
//            null,    //
//            null,    //
//            null,    //
//            null    //
//    );
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowInstanceMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.FlowInstance;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface FlowInstanceMapper extends BaseMapper<FlowInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepInstanceMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.FlowStepInstance;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface FlowStepInstanceMapper extends BaseMapper<FlowStepInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepLogMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.FlowStepLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface FlowStepLogMapper extends BaseMapper<FlowStepLog> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/FlowStepTemplateMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.FlowStepTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface FlowStepTemplateMapper extends BaseMapper<FlowStepTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/SubsystemFlowTemplateMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.SubsystemFlowTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface SubsystemFlowTemplateMapper extends BaseMapper<SubsystemFlowTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskInstanceMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.TaskInstance;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface TaskInstanceMapper extends BaseMapper<TaskInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskInstanceNodeMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.TaskInstanceNode;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface TaskInstanceNodeMapper extends BaseMapper<TaskInstanceNode> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskPathTemplateMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.TaskPathTemplate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface TaskPathTemplateMapper extends BaseMapper<TaskPathTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/mapper/TaskPathTemplateNodeMapper.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.mapper;
import com.vincent.rsf.server.system.entity.TaskPathTemplateNode;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface TaskPathTemplateNodeMapper extends BaseMapper<TaskPathTemplateNode> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowInstanceService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.FlowInstance;
public interface FlowInstanceService extends IService<FlowInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepInstanceService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.FlowStepInstance;
public interface FlowStepInstanceService extends IService<FlowStepInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepLogService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.FlowStepLog;
public interface FlowStepLogService extends IService<FlowStepLog> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/FlowStepTemplateService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.FlowStepTemplate;
public interface FlowStepTemplateService extends IService<FlowStepTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/SubsystemFlowTemplateService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.SubsystemFlowTemplate;
public interface SubsystemFlowTemplateService extends IService<SubsystemFlowTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskInstanceNodeService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.TaskInstanceNode;
public interface TaskInstanceNodeService extends IService<TaskInstanceNode> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskInstanceService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.TaskInstance;
public interface TaskInstanceService extends IService<TaskInstance> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskPathTemplateNodeService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.TaskPathTemplateNode;
public interface TaskPathTemplateNodeService extends IService<TaskPathTemplateNode> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/TaskPathTemplateService.java
New file
@@ -0,0 +1,8 @@
package com.vincent.rsf.server.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vincent.rsf.server.system.entity.TaskPathTemplate;
public interface TaskPathTemplateService extends IService<TaskPathTemplate> {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowInstanceServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.FlowInstanceMapper;
import com.vincent.rsf.server.system.entity.FlowInstance;
import com.vincent.rsf.server.system.service.FlowInstanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("flowInstanceService")
public class FlowInstanceServiceImpl extends ServiceImpl<FlowInstanceMapper, FlowInstance> implements FlowInstanceService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepInstanceServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.FlowStepInstanceMapper;
import com.vincent.rsf.server.system.entity.FlowStepInstance;
import com.vincent.rsf.server.system.service.FlowStepInstanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("flowStepInstanceService")
public class FlowStepInstanceServiceImpl extends ServiceImpl<FlowStepInstanceMapper, FlowStepInstance> implements FlowStepInstanceService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepLogServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.FlowStepLogMapper;
import com.vincent.rsf.server.system.entity.FlowStepLog;
import com.vincent.rsf.server.system.service.FlowStepLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("flowStepLogService")
public class FlowStepLogServiceImpl extends ServiceImpl<FlowStepLogMapper, FlowStepLog> implements FlowStepLogService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/FlowStepTemplateServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.FlowStepTemplateMapper;
import com.vincent.rsf.server.system.entity.FlowStepTemplate;
import com.vincent.rsf.server.system.service.FlowStepTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("flowStepTemplateService")
public class FlowStepTemplateServiceImpl extends ServiceImpl<FlowStepTemplateMapper, FlowStepTemplate> implements FlowStepTemplateService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/SubsystemFlowTemplateServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.SubsystemFlowTemplateMapper;
import com.vincent.rsf.server.system.entity.SubsystemFlowTemplate;
import com.vincent.rsf.server.system.service.SubsystemFlowTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("subsystemFlowTemplateService")
public class SubsystemFlowTemplateServiceImpl extends ServiceImpl<SubsystemFlowTemplateMapper, SubsystemFlowTemplate> implements SubsystemFlowTemplateService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskInstanceNodeServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.TaskInstanceNodeMapper;
import com.vincent.rsf.server.system.entity.TaskInstanceNode;
import com.vincent.rsf.server.system.service.TaskInstanceNodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("taskInstanceNodeService")
public class TaskInstanceNodeServiceImpl extends ServiceImpl<TaskInstanceNodeMapper, TaskInstanceNode> implements TaskInstanceNodeService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskInstanceServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.TaskInstanceMapper;
import com.vincent.rsf.server.system.entity.TaskInstance;
import com.vincent.rsf.server.system.service.TaskInstanceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("taskInstanceService")
public class TaskInstanceServiceImpl extends ServiceImpl<TaskInstanceMapper, TaskInstance> implements TaskInstanceService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskPathTemplateNodeServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.TaskPathTemplateNodeMapper;
import com.vincent.rsf.server.system.entity.TaskPathTemplateNode;
import com.vincent.rsf.server.system.service.TaskPathTemplateNodeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("taskPathTemplateNodeService")
public class TaskPathTemplateNodeServiceImpl extends ServiceImpl<TaskPathTemplateNodeMapper, TaskPathTemplateNode> implements TaskPathTemplateNodeService {
}
rsf-server/src/main/java/com/vincent/rsf/server/system/service/impl/TaskPathTemplateServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.vincent.rsf.server.system.service.impl;
import com.vincent.rsf.server.system.mapper.TaskPathTemplateMapper;
import com.vincent.rsf.server.system.entity.TaskPathTemplate;
import com.vincent.rsf.server.system.service.TaskPathTemplateService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("taskPathTemplateService")
public class TaskPathTemplateServiceImpl extends ServiceImpl<TaskPathTemplateMapper, TaskPathTemplate> implements TaskPathTemplateService {
}
rsf-server/src/main/java/flowInstance.sql
New file
@@ -0,0 +1,42 @@
-- save flowInstance record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.flowInstance', '0', '/system/flowInstance', 'flowInstance', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 实例化子流程主表', '', '1', 'system:flowInstance:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 实例化子流程主表', '', '1', 'system:flowInstance:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 实例化子流程主表', '', '1', 'system:flowInstance:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 实例化子流程主表', '', '1', 'system:flowInstance:remove', '3', '1', '1');
-- locale menu name
flowInstance: 'FlowInstance',
-- locale field
flowInstance: {
    flowInstanceNo: "flowInstanceNo",
    taskId: "taskId",
    taskNo: "taskNo",
    nodeInstanceId: "nodeInstanceId",
    nodeCode: "nodeCode",
    flowTemplateId: "flowTemplateId",
    flowTemplateCode: "flowTemplateCode",
    templateVersion: "templateVersion",
    currentStepCode: "currentStepCode",
    currentStepOrder: "currentStepOrder",
    executeParams: "executeParams",
    executeResult: "executeResult",
    errorCode: "errorCode",
    errorMessage: "errorMessage",
    startTime: "startTime",
    endTime: "endTime",
    timeoutAt: "timeoutAt",
    durationSeconds: "durationSeconds",
    retryTimes: "retryTimes",
    lastRetryTime: "lastRetryTime",
    contextData: "contextData",
},
-- ResourceContent
import flowInstance from './flowInstance';
case 'flowInstance':
    return flowInstance;
rsf-server/src/main/java/flowStepInstance.sql
New file
@@ -0,0 +1,37 @@
-- save flowStepInstance record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.flowStepInstance', '0', '/system/flowStepInstance', 'flowStepInstance', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 子流程步骤实例', '', '1', 'system:flowStepInstance:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 子流程步骤实例', '', '1', 'system:flowStepInstance:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 子流程步骤实例', '', '1', 'system:flowStepInstance:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 子流程步骤实例', '', '1', 'system:flowStepInstance:remove', '3', '1', '1');
-- locale menu name
flowStepInstance: 'FlowStepInstance',
-- locale field
flowStepInstance: {
    flowInstanceId: "flowInstanceId",
    flowInstanceNo: "flowInstanceNo",
    stepOrder: "stepOrder",
    stepCode: "stepCode",
    stepName: "stepName",
    stepType: "stepType",
    stepTemplateId: "stepTemplateId",
    executeResult: "executeResult",
    errorCode: "errorCode",
    errorMessage: "errorMessage",
    startTime: "startTime",
    endTime: "endTime",
    durationSeconds: "durationSeconds",
    inputData: "inputData",
    outputData: "outputData",
    retryTimes: "retryTimes",
},
-- ResourceContent
import flowStepInstance from './flowStepInstance';
case 'flowStepInstance':
    return flowStepInstance;
rsf-server/src/main/java/flowStepLog.sql
New file
@@ -0,0 +1,28 @@
-- save flowStepLog record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.flowStepLog', '0', '/system/flowStepLog', 'flowStepLog', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 步骤执行日志', '', '1', 'system:flowStepLog:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 步骤执行日志', '', '1', 'system:flowStepLog:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 步骤执行日志', '', '1', 'system:flowStepLog:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 步骤执行日志', '', '1', 'system:flowStepLog:remove', '3', '1', '1');
-- locale menu name
flowStepLog: 'FlowStepLog',
-- locale field
flowStepLog: {
    flowInstanceId: "flowInstanceId",
    stepInstanceId: "stepInstanceId",
    logType: "logType",
    logLevel: "logLevel",
    logContent: "logContent",
    requestData: "requestData",
    responseData: "responseData",
},
-- ResourceContent
import flowStepLog from './flowStepLog';
case 'flowStepLog':
    return flowStepLog;
rsf-server/src/main/java/flowStepTemplate.sql
New file
@@ -0,0 +1,36 @@
-- save flowStepTemplate record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.flowStepTemplate', '0', '/system/flowStepTemplate', 'flowStepTemplate', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 子流程步骤模板', '', '1', 'system:flowStepTemplate:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 子流程步骤模板', '', '1', 'system:flowStepTemplate:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 子流程步骤模板', '', '1', 'system:flowStepTemplate:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 子流程步骤模板', '', '1', 'system:flowStepTemplate:remove', '3', '1', '1');
-- locale menu name
flowStepTemplate: 'FlowStepTemplate',
-- locale field
flowStepTemplate: {
    flowId: "flowId",
    flowCode: "flowCode",
    stepOrder: "stepOrder",
    stepCode: "stepCode",
    stepName: "stepName",
    stepType: "stepType",
    actionType: "actionType",
    actionConfig: "actionConfig",
    inputMapping: "inputMapping",
    outputMapping: "outputMapping",
    conditionExpression: "conditionExpression",
    skipOnFail: "skipOnFail",
    retryEnabled: "retryEnabled",
    retryConfig: "retryConfig",
    timeoutSeconds: "timeoutSeconds",
},
-- ResourceContent
import flowStepTemplate from './flowStepTemplate';
case 'flowStepTemplate':
    return flowStepTemplate;
rsf-server/src/main/java/subsystemFlowTemplate.sql
New file
@@ -0,0 +1,35 @@
-- save subsystemFlowTemplate record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.subsystemFlowTemplate', '0', '/system/subsystemFlowTemplate', 'subsystemFlowTemplate', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 子系统模板', '', '1', 'system:subsystemFlowTemplate:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 子系统模板', '', '1', 'system:subsystemFlowTemplate:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 子系统模板', '', '1', 'system:subsystemFlowTemplate:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 子系统模板', '', '1', 'system:subsystemFlowTemplate:remove', '3', '1', '1');
-- locale menu name
subsystemFlowTemplate: 'SubsystemFlowTemplate',
-- locale field
subsystemFlowTemplate: {
    flowCode: "flowCode",
    flowName: "flowName",
    systemCode: "systemCode",
    systemName: "systemName",
    nodeType: "nodeType",
    version: "version",
    isCurrent: "isCurrent",
    effectiveTime: "effectiveTime",
    timeoutStrategy: "timeoutStrategy",
    timeoutSeconds: "timeoutSeconds",
    maxRetryTimes: "maxRetryTimes",
    needNotify: "needNotify",
    notifyTemplate: "notifyTemplate",
    remark: "remark",
},
-- ResourceContent
import subsystemFlowTemplate from './subsystemFlowTemplate';
case 'subsystemFlowTemplate':
    return subsystemFlowTemplate;
rsf-server/src/main/java/taskInstance.sql
New file
@@ -0,0 +1,51 @@
-- save taskInstance record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.taskInstance', '0', '/system/taskInstance', 'taskInstance', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 实际任务主表', '', '1', 'system:taskInstance:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 实际任务主表', '', '1', 'system:taskInstance:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 实际任务主表', '', '1', 'system:taskInstance:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 实际任务主表', '', '1', 'system:taskInstance:remove', '3', '1', '1');
-- locale menu name
taskInstance: 'TaskInstance',
-- locale field
taskInstance: {
    taskNo: "taskNo",
    bizNo: "bizNo",
    bizType: "bizType",
    templateId: "templateId",
    templateCode: "templateCode",
    templateVersion: "templateVersion",
    sourceInfo: "sourceInfo",
    targetInfo: "targetInfo",
    sourceCode: "sourceCode",
    targetCode: "targetCode",
    plannedPath: "plannedPath",
    actualPath: "actualPath",
    priority: "priority",
    timeoutAt: "timeoutAt",
    currentNodeCode: "currentNodeCode",
    currentNodeName: "currentNodeName",
    totalNodes: "totalNodes",
    completedNodes: "completedNodes",
    progressRate: "progressRate",
    estimatedDurationMinutes: "estimatedDurationMinutes",
    actualDurationMinutes: "actualDurationMinutes",
    startTime: "startTime",
    endTime: "endTime",
    resultCode: "resultCode",
    resultMessage: "resultMessage",
    resultData: "resultData",
    retryTimes: "retryTimes",
    lastRetryTime: "lastRetryTime",
    extParams: "extParams",
    remark: "remark",
},
-- ResourceContent
import taskInstance from './taskInstance';
case 'taskInstance':
    return taskInstance;
rsf-server/src/main/java/taskInstanceNode.sql
New file
@@ -0,0 +1,41 @@
-- save taskInstanceNode record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.taskInstanceNode', '0', '/system/taskInstanceNode', 'taskInstanceNode', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 任务执行节点明细表', '', '1', 'system:taskInstanceNode:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 任务执行节点明细表', '', '1', 'system:taskInstanceNode:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 任务执行节点明细表', '', '1', 'system:taskInstanceNode:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 任务执行节点明细表', '', '1', 'system:taskInstanceNode:remove', '3', '1', '1');
-- locale menu name
taskInstanceNode: 'TaskInstanceNode',
-- locale field
taskInstanceNode: {
    taskId: "taskId",
    taskNo: "taskNo",
    nodeOrder: "nodeOrder",
    nodeCode: "nodeCode",
    nodeName: "nodeName",
    nodeType: "nodeType",
    systemCode: "systemCode",
    systemName: "systemName",
    executeParams: "executeParams",
    executeResult: "executeResult",
    errorCode: "errorCode",
    errorMessage: "errorMessage",
    estimatedStartTime: "estimatedStartTime",
    actualStartTime: "actualStartTime",
    actualEndTime: "actualEndTime",
    timeoutAt: "timeoutAt",
    durationSeconds: "durationSeconds",
    retryTimes: "retryTimes",
    maxRetryTimes: "maxRetryTimes",
    dependsOnNodes: "dependsOnNodes",
},
-- ResourceContent
import taskInstanceNode from './taskInstanceNode';
case 'taskInstanceNode':
    return taskInstanceNode;
rsf-server/src/main/java/taskPathTemplate.sql
New file
@@ -0,0 +1,40 @@
-- save taskPathTemplate record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.taskPathTemplate', '0', '/system/taskPathTemplate', 'taskPathTemplate', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 路径模板主表', '', '1', 'system:taskPathTemplate:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 路径模板主表', '', '1', 'system:taskPathTemplate:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 路径模板主表', '', '1', 'system:taskPathTemplate:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 路径模板主表', '', '1', 'system:taskPathTemplate:remove', '3', '1', '1');
-- locale menu name
taskPathTemplate: 'TaskPathTemplate',
-- locale field
taskPathTemplate: {
    templateCode: "templateCode",
    templateName: "templateName",
    sourceType: "sourceType",
    targetType: "targetType",
    conditionExpression: "conditionExpression",
    conditionDesc: "conditionDesc",
    version: "version",
    isCurrent: "isCurrent",
    effectiveTime: "effectiveTime",
    expireTime: "expireTime",
    priority: "priority",
    timeoutMinutes: "timeoutMinutes",
    maxRetryTimes: "maxRetryTimes",
    retryIntervalSeconds: "retryIntervalSeconds",
    remark: "remark",
    createdBy: "createdBy",
    updatedBy: "updatedBy",
    createdTime: "createdTime",
    updatedTime: "updatedTime",
},
-- ResourceContent
import taskPathTemplate from './taskPathTemplate';
case 'taskPathTemplate':
    return taskPathTemplate;
rsf-server/src/main/java/taskPathTemplateNode.sql
New file
@@ -0,0 +1,37 @@
-- save taskPathTemplateNode record
-- mysql
insert into `sys_menu` ( `name`, `parent_id`, `route`, `component`, `type`, `sort`, `tenant_id`, `status`) values ( 'menu.taskPathTemplateNode', '0', '/system/taskPathTemplateNode', 'taskPathTemplateNode', '0' , '0', '1' , '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Query 路径节点明细表', '', '1', 'system:taskPathTemplateNode:list', '0', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Create 路径节点明细表', '', '1', 'system:taskPathTemplateNode:save', '1', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Update 路径节点明细表', '', '1', 'system:taskPathTemplateNode:update', '2', '1', '1');
insert into `sys_menu` ( `name`, `parent_id`, `type`, `authority`, `sort`, `tenant_id`, `status`) values ( 'Delete 路径节点明细表', '', '1', 'system:taskPathTemplateNode:remove', '3', '1', '1');
-- locale menu name
taskPathTemplateNode: 'TaskPathTemplateNode',
-- locale field
taskPathTemplateNode: {
    templateId: "templateId",
    templateCode: "templateCode",
    nodeOrder: "nodeOrder",
    nodeCode: "nodeCode",
    nodeName: "nodeName",
    nodeType: "nodeType",
    systemCode: "systemCode",
    systemName: "systemName",
    executeParams: "executeParams",
    resultSchema: "resultSchema",
    timeoutMinutes: "timeoutMinutes",
    mandatory: "mandatory",
    parallelExecutable: "parallelExecutable",
    preCondition: "preCondition",
    postCondition: "postCondition",
    nextNodeRules: "nextNodeRules",
},
-- ResourceContent
import taskPathTemplateNode from './taskPathTemplateNode';
case 'taskPathTemplateNode':
    return taskPathTemplateNode;
rsf-server/src/main/resources/mapper/system/FlowInstanceMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.FlowInstanceMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/FlowStepInstanceMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.FlowStepInstanceMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/FlowStepLogMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.FlowStepLogMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/FlowStepTemplateMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.FlowStepTemplateMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/SubsystemFlowTemplateMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.SubsystemFlowTemplateMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/TaskInstanceMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.TaskInstanceMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/TaskInstanceNodeMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.TaskInstanceNodeMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/TaskPathTemplateMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.TaskPathTemplateMapper">
</mapper>
rsf-server/src/main/resources/mapper/system/TaskPathTemplateNodeMapper.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vincent.rsf.server.system.mapper.TaskPathTemplateNodeMapper">
</mapper>