You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
445 lines
16 KiB
445 lines
16 KiB
<?php
|
|
class WorkFlow
|
|
{
|
|
private $formId;
|
|
private $systemId;
|
|
private $flowId;
|
|
private $mainFlow; //主线流程对象
|
|
public $currentFlow; //当前流程对象
|
|
private $workFlowParser;
|
|
public $flowContext;
|
|
private $currentAssigner;
|
|
private static $logPath = "log/workflow";
|
|
private $log;
|
|
private $formData;
|
|
private $nextAssignList;
|
|
private $tester; #测试人员数组
|
|
|
|
function __construct($systemId, $flowId, $formId, $formKey = null)
|
|
{
|
|
#实例化日志
|
|
$this->log = new Logger(dirname(__FILE__) . "/"
|
|
. (self::$logPath), Logger::DEBUG);
|
|
|
|
$this->systemId = $systemId;
|
|
$this->flowId = $flowId;
|
|
$this->formId = $formId;
|
|
|
|
$this->currentFlow = new Flow($formKey);
|
|
|
|
$_parentKey = $this->currentFlow->getParentKey();
|
|
//当流程不是处 于会签和子流程状态时 $mainFlow 和 $currentFlow是一个对象
|
|
$this->mainFlow = ($_parentKey == null or empty($_parentKey))
|
|
? $this->currentFlow : new Flow($_parentKey);
|
|
$this->workFlowParser = new WorkFlowParser($systemId, $flowId);
|
|
$this->flowContext = new FlowContext();
|
|
# var_dump( $this->flowContext);
|
|
// echo " WorkFLow 31:".$this->currentFlow->getFormKey();
|
|
|
|
$this->flowContext->setFormKey($this->currentFlow->getFormKey())
|
|
->setSystemId($this->systemId)
|
|
->setFlowId($this->flowId)
|
|
->setFormId($this->formId)
|
|
->setWorkFLowParser($this->workFlowParser);
|
|
|
|
$_SESSION['flowContext'] = serialize($this->flowContext);
|
|
// var_dump($this);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param $userId 流程初始化人员
|
|
*/
|
|
public function initWorkFlow($userId)
|
|
{ //var_dump($this->formId);
|
|
|
|
// var_dump($this);
|
|
$this->currentFlow->setSystemId($this->systemId)
|
|
->setFlowId($this->flowId)
|
|
->setFormId($this->formId)
|
|
->setFlowCode($this->getFirstFlowCode())
|
|
->save();
|
|
// var_dump($userId);
|
|
$this->flowContext->setNextAssigner($userId)
|
|
->setAssignStatus('S');
|
|
|
|
$start = new StartNodeHandler($this->workFlowParser->getFirstNode(), $this->flowContext, $this->formData);
|
|
// var_dump( $this->flowContext);
|
|
#执行开始节点预置的操作
|
|
$start->doWork();
|
|
#写入日志
|
|
// $this->log->logInfo("$userId 启动了流程 system:'" . $this->systemId . ";flow:" . $this->formId);
|
|
}
|
|
|
|
/**
|
|
* 设置多个签核接受人员
|
|
* @param array $members
|
|
*/
|
|
function setSplitMembers($members = array())
|
|
{
|
|
}
|
|
|
|
/**
|
|
*1.先检查是否满足签核下
|
|
*/
|
|
public function submit()
|
|
{
|
|
#获取FlowContext的值
|
|
$nextAssigner = $this->flowContext->getNextAssigner();
|
|
$assignStatus = $this->flowContext->getAssignStatus();
|
|
$assignOpinion = $this->flowContext->getAssignOpinion();
|
|
#获取所有下层Node数组
|
|
$nodes = $this->workFlowParser
|
|
->getNextNodes($this->currentFlow->getFlowCode());
|
|
#设置当前节点数据
|
|
$this->flowContext->setCurrentNode($this->workFlowParser
|
|
->getNodeByCode($this->currentFlow->getFlowCode()));
|
|
#设置要传入 Handler实例的Context 实例
|
|
|
|
$this->flowContext->getCurrentNode()->setFlow($this->flowContext)
|
|
->setformData($this->formData);
|
|
// $this->flowContext->getCurrentNode()->setformData($this->formData);
|
|
|
|
$asg = new Assign($this->currentFlow->getFormKey());
|
|
if (
|
|
$this->flowContext->getCurrentNode()->getType() == 'start_node'
|
|
and $asg->getSeq() == '0'
|
|
) {
|
|
$this->flowContext->setAssignStatus('S');
|
|
}
|
|
//var_dump(Subflow::getCurrentUser($this->currentFlow->getFormKey()));
|
|
$asg->setAssigner(Subflow::getCurrentUser($this->currentFlow->getFormKey()))
|
|
->setAssignStatus($this->flowContext->getAssignStatus())
|
|
->setAssignOpinion($assignOpinion)
|
|
->setFlowCode($this->currentFlow->getFlowCode())
|
|
->setFlowCodeSeq(0)->insert();
|
|
|
|
#记录日志
|
|
$_log_array = array(
|
|
"nextAssigner" => $nextAssigner,
|
|
"assignStatus" => $assignStatus,
|
|
"nextAssigner" => $nextAssigner,
|
|
"currentAssigner" => Subflow::getCurrentUser($this->currentFlow->getFormKey()),
|
|
"flow_code" => $this->currentFlow->getFlowCode()
|
|
);
|
|
$this->log->logInfo("" . ID . " 提交了流程 system:'" . $this->systemId . ";flow:" . $this->flowId, $_log_array);
|
|
|
|
#插入assign表信息
|
|
|
|
$_SESSION['flowContext'] = serialize($this->flowContext);
|
|
// var_dump($nodes);
|
|
foreach (Node::$nodeTypes as $type) {
|
|
if (!array_key_exists($type, $nodes)) continue;
|
|
foreach ($nodes[$type] as $node) {
|
|
$handleClass = get_class($node) . "Handler";
|
|
$obj = new $handleClass($node, $this->flowContext, $this->formData);
|
|
$obj->doWork();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
*获取签核人员列表
|
|
*/
|
|
public function getAssignerList()
|
|
{
|
|
$currentNode = $this->workFlowParser
|
|
->getNodeByCode($this->currentFlow->getFlowCode());
|
|
#获取当前签核者
|
|
$currentFormKey = $this->currentFlow->getFormKey();
|
|
$currentAssigner = Subflow::getCurrentUser($currentFormKey);
|
|
#读取签核类别 A是专人的签核
|
|
|
|
#遍历下层节点读取下层节点的签核人员
|
|
$currentNode->setFlow($this->flowContext)
|
|
->setFormData($this->formData);
|
|
$assignClass = $currentNode->getAssignClass();
|
|
|
|
if ($currentNode->checkTrust($assignClass, Employee::lead_code($currentAssigner))) {
|
|
|
|
#获取所有下层Node数组,并遍历,调用其中getAssignerList 方法
|
|
$nodes = $this->workFlowParser->getNextNodes($this->currentFlow->getFlowCode());
|
|
// var_dump($nodes);
|
|
|
|
$assigner = array();
|
|
foreach (Node::$nodeTypes as $type) {
|
|
if (!array_key_exists($type, $nodes)) continue;
|
|
foreach ($nodes[$type] as $node) {
|
|
if (method_exists($node, 'getAssignerList')) {
|
|
$assigner = array_merge(
|
|
(array)$assigner,
|
|
$node->getAssignerList($this->workFlowParser)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#检查退回选项
|
|
$backOption = $currentNode->getBackOption();
|
|
//B4 退回上一个节点
|
|
if ($backOption == 'B4') {
|
|
$prevNodes = $this->flowContext->workFlowParser->getPrevLevelNodes(
|
|
$currentNode->getNodeId(),
|
|
[Node::FLOW_NODE, Node::LOGIC_NODE]
|
|
);
|
|
foreach ($prevNodes as $key => $prevNode) {
|
|
$tmpNode = $prevNode[0];
|
|
$backAssign = Assign::get_lastest_record($currentFormKey, $tmpNode->getFlowCode());
|
|
$backUser = $backAssign['assigner'];
|
|
if (empty($backUser)) continue;
|
|
$nextAssignerStr = "";
|
|
$nextAssignerStr .= Employee::get_employee($backUser, $format = "employee_no-name") . ',';
|
|
array_push($assigner, array(0 => 'B4', 1 => $nextAssignerStr));
|
|
}
|
|
}
|
|
#B7 退回申请人
|
|
if ($backOption == 'B7') {
|
|
$assign = Assign::get_records($currentFormKey, true, '%', 'S');
|
|
// var_dump($assign);
|
|
$applicant = $assign[0]['assigner'];
|
|
$nextAssignerStr = "";
|
|
$nextAssignerStr .= Employee::get_employee($applicant, $format = "employee_no-name") . ',';
|
|
array_push($assigner, array(0 => 'B7', 1 => $nextAssignerStr));
|
|
}
|
|
|
|
#获取任务节点,查看是否有修改签核者的的任务
|
|
$task = new NodeTask();
|
|
$task->setFormKey($this->currentFlow->getFormKey())
|
|
->setFlowCode($this->currentFlow->getFlowCode())
|
|
->setState("OPEN")
|
|
->setPhase("LOAD");
|
|
$tasks = TaskManager::getTasks($task);
|
|
if (count($tasks) > 0) {
|
|
foreach ($tasks as $task) {
|
|
$handlerClass = NodeTask::$handlerClasses[constant("NodeTask::" . $task->getTaskType())];
|
|
$handler = new $handlerClass($this->flowContext, $this->formData);
|
|
if (method_exists($handler, 'setNextAssignerList')) {
|
|
|
|
$assigner = $handler->setNextAssignerList($assigner, $task);
|
|
}
|
|
}
|
|
}
|
|
|
|
#也可以指派给自己的下属
|
|
$subordinates = Employee::subordinates($currentAssigner);
|
|
if (count($subordinates) > 0) {
|
|
$nextAssignerStr = "";
|
|
foreach ($subordinates as $emp) {
|
|
$nextAssignerStr .= Employee::get_employee($emp, $format = "employee_no-name") . ',';
|
|
}
|
|
array_push($assigner, array(0 => 'FH', 1 => $nextAssignerStr));
|
|
}
|
|
|
|
$nextAssigner = $assigner;
|
|
} else {
|
|
#需要签给上级领导审
|
|
$nextAssigner = $currentNode->getDepartmentalAssignerList($currentAssigner);
|
|
# 获取任务节点,查看是否有修改签核者的的任务
|
|
$task = new NodeTask();
|
|
$task->setFormKey($this->currentFlow->getFormKey())
|
|
->setFlowCode($this->currentFlow->getFlowCode())
|
|
->setState("OPEN")
|
|
->setPhase("LOAD")
|
|
->setWfCondition('SAME');
|
|
$tasks = TaskManager::getTasks($task);
|
|
if (count($tasks) > 0) {
|
|
foreach ($tasks as $task) {
|
|
$handlerClass = NodeTask::$handlerClasses[constant("NodeTask::" . $task->getTaskType())];
|
|
$handler = new $handlerClass($this->flowContext, $this->formData);
|
|
if (method_exists($handler, 'setNextAssignerList')) {
|
|
$nextAssigner = $handler->setNextAssignerList($nextAssigner, $task);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->nextAssignList = $nextAssigner;
|
|
|
|
return $nextAssigner;
|
|
}
|
|
|
|
/**
|
|
*提交前测试表单数据是否满足表达提交条件
|
|
* 1.检测FlowContext对象的以下属性,为空不可提交
|
|
*/
|
|
public function submitTest()
|
|
{
|
|
$errorArray = array();
|
|
#1.检查FlowContext的属性是否都被设置
|
|
$flowContextRequiredProperty = array(
|
|
"systemId", "flowId", "formId", "currentAssigner", "flowCode", "nextAssigner", "assignStatus", "assignOpinion", "formKey"
|
|
);
|
|
foreach ($this->flowContext as $key => $value) {
|
|
if (in_array($key, $flowContextRequiredProperty) and empty($value)) {
|
|
array_push($errorArray, "FlowContext:" . $key . " 属性异常. Value:" . $value);
|
|
}
|
|
}
|
|
#2. 当前登陆人员与Sublfow:Current_user 不符合时,不允许提交
|
|
|
|
$currentAssignerId = $this->flowContext->getCurrentUser();
|
|
if (!empty($currentAssignerId) and ID == $currentAssignerId) {
|
|
array_push($errorArray, "签核已提交,请勿重复操作.");
|
|
}
|
|
return $errorArray;
|
|
}
|
|
|
|
/**
|
|
*返回assignStatus
|
|
* @param $nextAssigner
|
|
* @return string
|
|
*/
|
|
public function getAssignStatus($nextAssigner)
|
|
{
|
|
|
|
$htmlOption = "'<option value=00000 >請選擇</option>'";
|
|
foreach ($nextAssigner as $assigner) {
|
|
|
|
$htmlOption .= "<option value=" . $assigner[0] . ">"
|
|
. Code::getContent('assign_status', $assigner[0]) . "</option>";
|
|
}
|
|
|
|
return $htmlOption;
|
|
}
|
|
|
|
/**
|
|
*获取会签部门
|
|
* @param null $flowCode 当前流程的流程码
|
|
* @return array
|
|
*/
|
|
public function getCounterSignDepart($flowCode = null)
|
|
{
|
|
$flowCode = empty($flowCode) ? $this->flowContext->getFlowCode() : $flowCode;
|
|
/* TODO 从会签节点读取配置的会签属性,并返回成员数组*/
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 是否允许拆分
|
|
* @return bool
|
|
*/
|
|
public function isSplitable()
|
|
{
|
|
$nodes = $this->workFlowParser->getNextNodes(
|
|
$this->currentFlow->getFlowCode(),
|
|
[Node::COUNTER_SIGN_TASK]
|
|
);
|
|
if (count($nodes) == 0) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
*1.检查下个节点的类型,为Split节点时 ,返回Split节点下各层节点人员
|
|
*/
|
|
public function getSubflowMembers()
|
|
{
|
|
$nodes = $this->workFlowParser->getNextNodes(
|
|
$this->currentFlow->getFlowCode(),
|
|
[Node::SPLIT_NODE]
|
|
);
|
|
if (count($nodes) == 0) {
|
|
return null;
|
|
}
|
|
$splitNode = $nodes[Node::SPLIT_NODE][0];
|
|
$assigner = $splitNode->getSplitMembers($this->workFlowParser);
|
|
return $assigner;
|
|
}
|
|
|
|
/**
|
|
* 获取第一个流程节点
|
|
* @return mixed
|
|
*/
|
|
public function getFirstFlowCode()
|
|
{
|
|
|
|
$node = $this->workFlowParser->getFirstNode();
|
|
return $node->getFlowCode();
|
|
}
|
|
|
|
/**
|
|
* 获取流程的名称
|
|
* @return mixed
|
|
*/
|
|
public function getFlowName()
|
|
{
|
|
$flowInfo = $this->workFlowParser->getFlowInfo();
|
|
return $flowInfo['flowName'];
|
|
}
|
|
|
|
/**
|
|
*获取流程版本
|
|
*/
|
|
function getFlowVersion()
|
|
{
|
|
$flowInfo = $this->workFlowParser->getFlowInfo();
|
|
return $flowInfo['version'];
|
|
}
|
|
|
|
/**
|
|
* 获取流程需要的调单数据
|
|
* @return mixed
|
|
*/
|
|
public function getFormData()
|
|
{
|
|
return $this->formData;
|
|
}
|
|
|
|
/**
|
|
* 设置表单里面的值
|
|
* @param mixed $formData
|
|
*/
|
|
public function setFormData($formData)
|
|
{
|
|
$this->formData = $formData;
|
|
$nextUser = empty($formData['next_users']) ? "" : $formData['next_users'];
|
|
$assignStatus = empty($formData['assign_status']) ? "" : $formData['assign_status'];
|
|
$assignOpinion = empty($formData['assign_opinion']) ? "" : $formData['assign_opinion'];
|
|
$currentAssignerId = empty($formData['current_assigner']) ? ID : $formData['current_assigner'];
|
|
$this->flowContext->setAssignOpinion($assignOpinion)
|
|
->setNextAssigner($nextUser)
|
|
->setAssignStatus($assignStatus)
|
|
->setFormKey($this->currentFlow->getFormKey())
|
|
->setFlowCode($this->currentFlow->getFlowCode())
|
|
->setCurrentUser($currentAssignerId);
|
|
}
|
|
|
|
/**
|
|
* 获取节点的
|
|
* @param $flowCode
|
|
* @return String
|
|
*/
|
|
public function getNodeDescriptions($flowCode)
|
|
{
|
|
$node = $this->workFlowParser->getNodeByCode($flowCode);
|
|
return $node->getNodeDescription();
|
|
}
|
|
|
|
/**
|
|
* 获取节点的节点
|
|
* @param $flowCode
|
|
* @return String
|
|
*/
|
|
public function getCurrentNode($flowCode = null)
|
|
{
|
|
$flowCode = empty($flowCode) ? $this->currentFlow->getFlowCode() : $flowCode;
|
|
$node = $this->workFlowParser->getNodeByCode($flowCode);
|
|
return $node;
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getTester()
|
|
{
|
|
return $this->tester;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $tester
|
|
*/
|
|
public function setTester($tester)
|
|
{
|
|
$this->tester = $tester;
|
|
}
|
|
}
|
|
|