617 lines
29 KiB
PHP
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);
|
|
}
|
|
}
|