Files
swiftadmin/app/admin/controller/easyflow/FlowEngine.php
2024-07-13 12:53:20 +08:00

617 lines
29 KiB
PHP

<?php
declare (strict_types = 1);
namespace app\admin\controller\easyflow;
use app;
use app\AdminController;
use app\admin\model\FlowGroup as FlowGroupModel;
use Exception;
use think\facade\Db;
/**
* flow_group
* 分组
*/
class FlowEngine extends AdminController
{
/**
* FlowGroup模型对象
* @var \app\admin\model\FlowGroup
*/
public $admin = [];
public $tplsharing = 'add';
public $noNeedAuth = ['*'];
public function __construct()
{
parent::__construct();
}
public function start(){
Db::startTrans();
try{
$data = request()->post();
$data = $data['data'];
$formdata = $data['data'];
$this->admin = get_admin_info();
$originator = $this->admin['id'];//发起人
$flowid = $data['flowid'];
$flow = Db::name('flow_scheme')->where('id',$flowid)->find();
$vformJson = json_decode($flow['formitems'],true);
$widgetList = $vformJson['widgetList'];
$controleList = [];
//判断 如果值为数组的话需要转为字符串
foreach($widgetList as $k){
$controleList[$k['options']['name']]=$k;
}
//判断回传的字段类型处理,有一些多选 是数组需要转字符串
$mControlList = array("picture-upload","select","cascader",'file-upload');
foreach($formdata as $d => $v){
$sc = $controleList[$d];
if(($sc['type'] == 'picture-upload' || $sc['type'] == 'file-upload') && isset($formdata[$d])){
$fileData = $formdata[$d];
foreach($fileData as $f){
if(isset($f['response'])){
$f['url'] = $f['response']['url'];
}
}
$formdata[$d] = json_encode($fileData);
}
else if($sc && (in_array($sc['type'],$mControlList))){
$formdata[$d] = json_encode($formdata[$d]);
}
}
$table = $flow['bizscheme'];
$insertId = Db::table($table)->strict(false)->insertGetId($formdata);
$today = str_replace('-','',date("Y-m-d"));
//新建流程实例
$instanceId= Db::name('flow_instance')->insertGetId(array(
'originator' => $originator,
'scheme' => $flowid,
'createtime' => date("Y-m-d H:i:s"),
'instancecode' => time(),
'bizobjectid' => $insertId,
'instancestatus' => 1,
'title'=>$flow['name'].'-'.$today.str_pad($insertId,5,'0',STR_PAD_LEFT),
'completedtime' => '1990-01-01 00:00:00',
));
//获取发起流程节点
$process = json_decode($flow['process'],true);
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $process['name'],
'type'=>'root',
'stepid' => $process['id'],
'receiveid' => $originator,
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 2,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
//寻找下一个节点
if(isset($process['children'])){
$currentNode = $process['children'];
$nodeType = $currentNode['type'];
$normal = 0;
switch($nodeType){
//指定人员
case 'CONDITIONS':
//获取所有条件分支
$branchsList = $currentNode['branchs'];
//判断符合条件的分支
foreach($branchsList as $branch){
try {
$express = $branch['props']['expression'];
$sql = "select * from (select * from " . $table . " where id = '" . $insertId . "') a where " . $express;
$tableRes = Db::query($sql);
if (count((array)$tableRes) >= 1) {
$normal++;
//下一个节点逻辑
$currentNode = $branch['children'];
$spType = $currentNode['props']['assignedType'];
switch($spType){
case 'ASSIGN_USER':
$userIdList = $currentNode['props']['assignedUser'];
foreach($userIdList as $user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'type'=>'node',
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
break;
case 'ROLE':
$roleList = $currentNode['props']['role'];
foreach($roleList as $jobid){
//$userList = Db::name('admin')->where(['jobs_id'=>$jobid['id']])->select();
$userList = Db::name('admin')->where("FIND_IN_SET('".$jobid['id']."',jobs_id)")->select();
foreach($userList as $row =>$user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'type'=>'node',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
}
break;
}
continue;
}
} catch (\think\Exception $e) {
continue;
}
}
if($normal == 0){
throw new Exception('找不到下一个流程节点,请联系管理员');
}
break;
case 'APPROVAL':
$spType = $currentNode['props']['assignedType'];
switch($spType){
case 'ASSIGN_USER':
$userIdList = $currentNode['props']['assignedUser'];
foreach($userIdList as $user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'type'=>'node',
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
break;
case 'ROLE':
$roleList = $currentNode['props']['role'];
foreach($roleList as $jobid){
//$userList = Db::name('admin')->where(['jobs_id'=>$jobid['id']])->select();
$userList = Db::name('admin')->where("FIND_IN_SET('".$jobid['id']."',jobs_id)")->select();
foreach($userList as $row =>$user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'type'=>'node',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
}
break;
}
break;
case 'CONDITION':
break;
}
}else{
//流程结束
Db::name('flow_instance')->where('id', $instanceId)->update(['instancestatus' => '2']);
}
Db::commit();
$result =['code' =>200,'msg' =>'提交成功'.$instanceId] ;
}
catch(Exception $ex){
$result =['code' =>500,'msg' => $ex->getMessage()] ;
Db::rollback();
}
return json($result);
}
/**拒绝流程
* @param $taskid
* @param string $comment
* @return bool
* @throws Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function refuse()
{
$params = \request()->all();
$taskid = $params['taskid'];
$comment = $params['comment'];
$task = Db::name('flow_task')->where(['id' => $taskid, 'status' => 0])->find();
if (!$task)
throw new Exception('找不到当前任务,或已处理,请联系管理员');
//更改当前流程为拒绝状态
$comment = $comment == '' ? '[同意]' : $comment;
Db::name('flow_task')->where('id', $taskid)
->update(['status' => 2, 'completedtime' => date("Y-m-d H:i:s"), 'comment' => $comment]);
//取消其他流程
Db::name('flow_task')->where(['instanceid' => $task['instanceid'], 'status' => 0])
->update(['status' => 3, 'completedtime' => date("Y-m-d H:i:s")]);
//更改流程实例为草稿状态
Db::name('flow_instance')->where(['id' => $task['instanceid']])
->update(['instancestatus' => 0]);
//寻找下一个待办任务
$startNode = Db::name('flow_task')->where(['instanceid' => $task['instanceid'], 'type' => 'root'])->find();
//$startNode->status = 0;
Db::name('flow_task')->insert([
'flowid' => $startNode['flowid'],
'stepname' => $startNode['stepname'],
'type'=>'root',
'stepid' => $startNode['stepid'],
'receiveid' => $startNode['receiveid'],
'instanceid' => $startNode['instanceid'],
'senderid' => $startNode['senderid'],
'status' => '0',
'createtime' => date("Y-m-d H:i:s")
]);
$result =['code' =>200,'msg'=>'提交成功'] ;
return json($result);
}
/**取消流程
* @param $taskid
* @param string $comment
* @return bool
* @throws \think\exception\DbException
*/
public function cancel()
{
$params = \request()->all();
$taskid = $params['taskid'];
$comment = $params['comment'];
$res = true;
$task = $this->task->get($taskid);
$comment = $comment == '' ? '[取消]' : $comment;
//更改当前流程为取消状态
$this->task->where(['instanceid' => $task['instanceid']])->where('status', 'in', [0, 1])->update(['status' => 3, 'completedtime' => date("Y-m-d H:i:s"), 'comment' => $comment]);
$this->instance->where(['id' => $task['instanceid']])->update(['instancestatus' => 3]);
return $res;
}
/**同意流程
* @param $taskid
* @param string $comment
* @return bool
* @throws \think\exception\DbException
*/
public function agree()
{
Db::startTrans();
try{
$params = \request()->all();
$taskid = $params['taskid'];
$comment = $params['comment'];
$comment = $comment==''?'[同意]':$comment;
$this->admin = get_admin_info();
$task = Db::name('flow_task')->where(['id' => $taskid, 'status' => 0])->find();
if (!$task){
throw new Exception('找不到当前任务,或已处理,请联系管理员');
}
else{
Db::name('flow_task')->where('id', $taskid)->update(['comment'=>$comment,'status' => '2','completedtime'=>date("Y-m-d H:i:s")]);
}
$originator = $this->admin['id'];//发起人
$flowid = $task['flowid'];
$instanceId = $task['instanceid'];
$flow = Db::name('flow_scheme')->where('id',$task['flowid'])->find();
$instance = Db::name('flow_instance')->where('id',$task['instanceid'])->find();
$insertId = $instance['bizobjectid'];
$table = $flow['bizscheme'];
$process = json_decode($flow['process'],true);
$currentNode = $this->getNode($task['stepid'],$process);
//寻找下一个节点
if($currentNode){
$nodeType = $currentNode['type'];
switch($nodeType){
case 'APPROVAL':
$spType = $currentNode['props']['assignedType'];
switch($spType){
case 'ASSIGN_USER':
$userIdList = $spType = $currentNode['props']['assignedUser'];
foreach($userIdList as $user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'type'=>'node',
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => $task['stepid'],
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => ''
));
}
break;
case 'ROLE':
$roleList = $currentNode['props']['role'];
foreach($roleList as $jobid){
$userList = Db::name('admin')->where(['jobs_id'=>$jobid])->select();
foreach($userList as $row =>$user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'type'=>'node',
'prevstepid' => $task['stepid'],
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => ''
));
}
}
break;
}
break;
case 'CONDITIONS':
//获取所有条件分支
$branchsList = $currentNode['branchs'];
$normal = 0;
//判断符合条件的分支
foreach($branchsList as $branch){
try {
$express = $branch['props']['expression'];
$sql = "select * from (select * from " . $table . " where id = '" . $insertId . "') a where " . $express;
$tableRes = Db::query($sql);
if (count((array)$tableRes) >= 1) {
$normal++;
//下一个节点逻辑
$currentNode = $branch['children'];
$spType = $currentNode['props']['assignedType'];
switch($spType){
case 'ASSIGN_USER':
$userIdList = $currentNode['props']['assignedUser'];
foreach($userIdList as $user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'type'=>'node',
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
break;
case 'ROLE':
$roleList = $currentNode['props']['role'];
foreach($roleList as $jobid){
//$userList = Db::name('admin')->where(['jobs_id'=>$jobid['id']])->select();
$userList = Db::name('admin')->where("FIND_IN_SET('".$jobid['id']."',jobs_id)")->select();
foreach($userList as $row =>$user){
Db::name('flow_task')->save(array(
'flowid' => $flowid,
'stepname' => $currentNode['name'],
'stepid' => $currentNode['id'],
'receiveid' => $user['id'],
'prevstepid' => '10000',
'type'=>'node',
'instanceid' => $instanceId,
'senderid' => $originator,
'status' => 0,
'createtime' => date("Y-m-d H:i:s"),
'completedtime' => date("Y-m-d H:i:s"),
'comment' => '提交'
));
}
}
break;
}
continue;
}
} catch (\think\Exception $e) {
continue;
}
}
if($normal == 0){
throw new Exception('找不到下一个流程节点,请联系管理员');
}
break;
}
}else{
//流程结束
Db::name('flow_instance')->where('id', $instanceId)->update(['instancestatus' => '2']);
}
Db::commit();
$result =['code' =>200,'msg' =>'提交成功'.$instanceId] ;
}
catch(Exception $ex){
$result =['code' =>500,'msg' => $ex->getMessage()] ;
Db::rollback();
}
return json($result);
}
public function getFlowForm($id)
{
$msg='';
$instanceId = '';
$params = \request()->all();
$id = request()->input('id');
if(isset($params['instanceId']))
{
$instanceId = $params['instanceId'];
}
else
{
$task = Db::name('flow_task')->where('id',$id)->find();
$instanceId = $task['instanceid'];
}
$instance = Db::name('flow_instance')->where('id',$instanceId)->find();
$scheme = Db::name('flow_scheme')->where('id', $instance['scheme'])->find();
$formData = Db::table($scheme['bizscheme'])->where('id',$instance['bizobjectid'])->find();
$vformJson = json_decode($scheme['formitems'],true);
$widgetList = $vformJson['widgetList'];
$controleList = [];
//判断 如果值为数组的话需要转为字符串
foreach($widgetList as $k){
$controleList[$k['options']['name']]=$k;
}
//判断回传的字段类型处理,有一些多选 是数组需要转字符串
$mControlList = array("picture-upload","file-upload","select","cascader");
foreach($formData as $d => $v){
if( $d == 'id'){
continue;
}
//$sc = $controleList[$d];
if(isset($controleList[$d]) && (in_array($controleList[$d]['type'],$mControlList))){
$formData[$d] =$formData[$d]? json_decode($formData[$d],true):[];
}
}
$history = Db::name('flow_workitem_view')
->where(['instanceid'=>$instanceId,'status'=>2])
->order('taskcreatetime', 'desc')->select();
$data = ['process'=>$scheme['process'],'formitems'=>$scheme['formitems'],'formdata'=>$formData,'history'=>$history];
$result =['code' =>200,'data' =>$data,'msg'=>$msg] ;
return json($result);
}
/**
* id 要寻找的父节点id
* node 当前遍历的节点用来判断类型
* json 当前遍历的节点
*/
public function getNode($id,$node)
{
if(!isset($node['children']) || empty($node['children'])){
return [];
}
//处理当前节点为开始节点 驳回重新提交
else if($id =='root'){
return $node['children'];
}
//处理非开始节点
else if($this->isPrimaryNode($node)){
if(isset($node['children']['children']) && $node['children']['id'] == $id){
return $node['children']['children'];
}
return $this->getNode($id,$node['children']);
}
//循环每个分支节点
else if($this->isBranchNode($node)){
$branchs = $node['branchs'];
foreach($branchs as $branch){
$nodeFind = $this->getNode($id,$branchs['children']);
if($nodeFind){
return $nodeFind;
}
}
return $this->getNode($id,$node['children']);
}
else if($node['type'] === 'EMPTY'){
return [];
}
else{
return $this->getNode($id,$node['children']);
}
}
public function isPrimaryNode($node)
{
return $node &&
($node['type'] === 'ROOT' || $node['type'] === 'APPROVAL'
|| $node['type'] === 'CC' || $node['type'] === 'DELAY'
|| $node['type'] === 'TRIGGER');
}
public function isBranchNode($node)
{
return $node && ($node['type'] === 'CONDITIONS' || $node['type'] === 'CONCURRENTS');
}
public function isEmptyNode($node)
{
return $node && ($node['type'] === 'EMPTY');
}
public function deletetask($id)
{
$id = request()->input('id');
Db::name('flow_task')->where('id',$id)->delete();
$result =['code' =>200,'data' =>'','msg'=>'删除成功'] ;
return json($result);
}
public function canceltask($id)
{
$id = request()->input('id');
Db::name('flow_task')->where('id',$id)->update(['status'=>3]);
$task = Db::name('flow_task')->where('id',$id)->find();
$instancid = $task['instanceid'];
$isalltask = Db::name('flow_task')
->where('instanceid',$instancid)
->where([['id', '<>', $id]])
->where([['status', '=', 0]])
->find();
if(!$isalltask){
Db::name('flow_instance')->where('id',$instancid)->update(['instancestatus'=>3]);
}
$result =['code' =>200,'data' =>'','msg'=>'取消成功'] ;
return json($result);
}
public function forwardtask()
{
$id = request()->input('id');
$taskid = request()->input('taskid');
Db::name('flow_task')->where('id',$taskid)->update(['receiveid'=>$id]);
$result =['code' =>200,'data' =>'','msg'=>'转发成功'] ;
return json($result);
}
}