workflow_flutter 1.0.0
workflow_flutter: ^1.0.0 copied to clipboard
A powerful Flutter workflow management plugin, supporting Android, iOS, macOS, Windows, web, and Linux platforms.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:workflow_flutter/workflow_flutter.dart';
import 'package:workflow_flutter/models/workflow_models.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _workflowFlutter = WorkflowFlutter.instance;
// State variables
List<Workflow> _workflows = [];
Workflow? _selectedWorkflow;
WorkflowExecutionResult? _lastExecutionResult;
String _currentEvent = "";
final List<String> _eventLog = [];
String _workflowName = "示例工作流";
String _workflowDescription = "这是一个示例工作流";
// Controllers
final _eventLogController = ScrollController();
@override
void initState() {
super.initState();
// Initialize workflow event listener
_initWorkflowEventListener();
// Load existing workflows
_loadWorkflows();
}
@override
void dispose() {
_eventLogController.dispose();
super.dispose();
}
// Initialize workflow event listener
void _initWorkflowEventListener() {
_workflowFlutter.listenWorkflowEvents().listen((event) {
setState(() {
_currentEvent = "${event.eventType} (${event.timestamp})";
_eventLog.add(
"[${event.timestamp}] ${event.eventType}: ${event.executionId}",
);
// Auto scroll to bottom
Timer(const Duration(milliseconds: 100), () {
_eventLogController.jumpTo(
_eventLogController.position.maxScrollExtent,
);
});
});
});
}
// Load all workflows
Future<void> _loadWorkflows() async {
try {
final workflows = await _workflowFlutter.listWorkflows();
setState(() {
_workflows = workflows;
});
} catch (e) {
_showError("加载工作流失败: $e");
}
}
// Create new workflow
Future<void> _createWorkflow() async {
try {
final workflow = Workflow(
id: "", // Empty ID for plugin to generate automatically
name: _workflowName,
description: _workflowDescription,
steps: [
WorkflowStep(
id: "step1",
name: "第一步",
type: WorkflowStepType.action,
parameters: {
"description": "执行第一步任务",
"action": "action1",
"inputParameters": {},
"outputParameters": {},
"transitionConditions": {"success": "step2", "failure": "end"},
},
onSuccess: ["step2"],
onFailure: [],
),
WorkflowStep(
id: "step2",
name: "第二步",
type: WorkflowStepType.action,
parameters: {
"description": "执行第二步任务",
"action": "action2",
"inputParameters": {},
"outputParameters": {},
"transitionConditions": {"success": "end", "failure": "end"},
},
onSuccess: [],
onFailure: [],
),
],
status: WorkflowStatus.pending,
);
final createdWorkflow = await _workflowFlutter.createWorkflow(workflow);
setState(() {
_workflows.add(createdWorkflow);
_selectedWorkflow = createdWorkflow;
});
_showSuccess("工作流创建成功: ${createdWorkflow.name}");
} catch (e) {
_showError("创建工作流失败: $e");
}
}
// Execute workflow
Future<void> _executeWorkflow() async {
if (_selectedWorkflow == null) {
_showError("请先选择一个工作流");
return;
}
try {
final inputData = {"param1": "value1", "param2": 123, "param3": true};
final executionResult = await _workflowFlutter.executeWorkflow(
_selectedWorkflow!.id,
inputData: inputData,
);
setState(() {
_lastExecutionResult = executionResult;
});
_showSuccess("工作流执行已启动: ${executionResult.executionId}");
} catch (e) {
_showError("执行工作流失败: $e");
}
}
// Cancel workflow execution
Future<void> _cancelWorkflowExecution() async {
if (_lastExecutionResult == null ||
_lastExecutionResult!.status == WorkflowStatus.completed) {
_showError("没有可取消的工作流执行");
return;
}
try {
await _workflowFlutter.cancelWorkflowExecution(
_lastExecutionResult!.executionId,
);
_showSuccess("工作流执行已取消");
} catch (e) {
_showError("取消工作流执行失败: $e");
}
}
// Get workflow execution result
Future<void> _getExecutionResult() async {
if (_lastExecutionResult == null) {
_showError("没有执行结果可查询");
return;
}
try {
final result = await _workflowFlutter.getWorkflowExecutionResult(
_lastExecutionResult!.executionId,
);
setState(() {
_lastExecutionResult = result;
});
_showSuccess("执行结果已更新");
} catch (e) {
_showError("获取执行结果失败: $e");
}
}
// Delete workflow
Future<void> _deleteWorkflow() async {
if (_selectedWorkflow == null) {
_showError("请先选择一个工作流");
return;
}
try {
await _workflowFlutter.deleteWorkflow(_selectedWorkflow!.id);
setState(() {
_workflows.remove(_selectedWorkflow);
_selectedWorkflow = null;
if (_workflows.isNotEmpty) {
_selectedWorkflow = _workflows.first;
}
});
_showSuccess("工作流已删除");
} catch (e) {
_showError("删除工作流失败: $e");
}
}
// Show success message
void _showSuccess(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message), backgroundColor: Colors.green),
);
}
// Show error message
void _showError(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message), backgroundColor: Colors.red),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Workflow Flutter Example App')),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Current event display
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'当前事件',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 8),
Text(_currentEvent.isEmpty ? '暂无事件' : _currentEvent),
],
),
),
),
const SizedBox(height: 16),
// Create workflow form
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'创建新工作流',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
TextField(
decoration: const InputDecoration(
labelText: '工作流名称',
border: OutlineInputBorder(),
),
onChanged: (value) => _workflowName = value,
controller: TextEditingController(
text: _workflowName,
),
),
const SizedBox(height: 12),
TextField(
decoration: const InputDecoration(
labelText: '工作流描述',
border: OutlineInputBorder(),
),
onChanged: (value) => _workflowDescription = value,
controller: TextEditingController(
text: _workflowDescription,
),
maxLines: 2,
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _createWorkflow,
child: const Text('创建工作流'),
),
],
),
),
),
const SizedBox(height: 16),
// Workflow list and operations
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'工作流列表',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
// Workflow selector
DropdownButtonFormField<Workflow>(
decoration: const InputDecoration(
labelText: '选择工作流',
border: OutlineInputBorder(),
),
initialValue: _selectedWorkflow,
items: _workflows.map((workflow) {
return DropdownMenuItem(
value: workflow,
child: Text(workflow.name),
);
}).toList(),
onChanged: (value) {
setState(() {
_selectedWorkflow = value;
});
},
hint: const Text('选择一个工作流'),
),
const SizedBox(height: 16),
// Workflow action buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _executeWorkflow,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
child: const Text('执行工作流'),
),
ElevatedButton(
onPressed: _cancelWorkflowExecution,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
),
child: const Text('取消执行'),
),
ElevatedButton(
onPressed: _deleteWorkflow,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
),
child: const Text('删除工作流'),
),
],
),
const SizedBox(height: 16),
// Execution result
if (_lastExecutionResult != null) ...[
Text(
'执行结果',
style: Theme.of(context).textTheme.titleSmall,
),
const SizedBox(height: 8),
Text('执行ID: ${_lastExecutionResult!.executionId}'),
Text('状态: ${_lastExecutionResult!.status}'),
Text('开始时间: ${_lastExecutionResult!.startedAt}'),
if (_lastExecutionResult!.completedAt != null) ...[
Text('完成时间: ${_lastExecutionResult!.completedAt!}'),
],
Text('结果: ${_lastExecutionResult!.result}'),
if (_lastExecutionResult!.error != null) ...[
Text('错误: ${_lastExecutionResult!.error}'),
],
const SizedBox(height: 8),
ElevatedButton(
onPressed: _getExecutionResult,
child: const Text('刷新执行结果'),
),
],
],
),
),
),
const SizedBox(height: 16),
// Event log
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'事件日志',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
SizedBox(
height: 200,
child: ListView.builder(
controller: _eventLogController,
itemCount: _eventLog.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 4.0,
),
child: Text(_eventLog[index]),
);
},
),
),
],
),
),
),
],
),
),
),
),
);
}
}