gdoo/app/Gdoo/Model/Services/StepService.php

615 lines
21 KiB
PHP

<?php namespace Gdoo\Model\Services;
use Auth;
use DB;
use App\Support\Hook;
use Gdoo\Model\Models\Step;
class StepService
{
/**
* 获取下一步审核节点和抄送节点
*/
public static function getNextSteps($steps, $parent_id, $params) {
static $ret;
foreach ($steps as $step) {
if ($step['join']) {
// 获取自己的下级
$join = explode(',', $step['join']);
foreach ($join as $step_next_id) {
if ($step['step_id'] == $parent_id) {
$step_next = $steps[$step_next_id];
$step_id = $step_next['step_id'];
$step_next['run_step_id'] = $step_next['id'];
$step_next['id'] = $step_id;
$step_next['parent_id'] = $parent_id;
// 多条路径形成的bug(多个审核节点接连到相同节点时会出现)
if (isset($ret[$step_next['step_id']])) {
$step_id = $step_id.'.'.$parent_id;
}
// 检查条件(不满足就跳过,不管是知会还是审核)
if (static::checkCondition($step, [$step_next], $params)) {
$step_user = static::getStepUser($step_next, $params);
$step_next = $step_user['step'];
$continue = $step_user['continue'];
$ret[$step_id] = $step_next;
// 节点是审核节点时不再获取下一个节点
if ($step['option'] == 1) {
if ($continue) {
continue;
}
}
} else {
continue;
}
static::getNextSteps($steps, $step_next_id, $params);
}
}
}
}
return $ret;
}
/**
* 获取上一步审核节点和抄送节点
*/
public static function getBackSteps($steps, $parent_id, $params) {
static $ret;
foreach ($steps as $step) {
if ($step['join']) {
// 获取自己的下级
$join = explode(',', $step['join']);
foreach ($join as $step_next_id) {
if ($step_next_id == $parent_id) {
$step_next = $steps[$parent_id];
$step_id = $step['step_id'];
$step['run_step_id'] = $step['id'];
$step['id'] = $step_id;
$step['parent_id'] = $parent_id;
// 检查条件
if (static::checkCondition($step, [$step_next], $params)) {
$step_user = static::getStepUser($step, $params);
$step = $step_user['step'];
$continue = $step_user['continue'];
$ret[$step_id] = $step;
// 节点是审核节点时不再获取下一个节点
if ($step['option'] == 1) {
if ($continue) {
continue;
}
}
} else {
continue;
}
static::getBackSteps($steps, $step_id, $params);
}
}
}
}
return $ret;
}
/**
* 匹配节点相关人员
*/
public static function getStepUser($step, $params) {
$master = $params['master'];
$table = $master['table'];
$id = $master['id'];
$data = $params[$table];
$user_ids = static::getUser($params, $step, $master['auth'], $table, $data, $id);
$step['user_ids'] = DB::table('user')->whereIn('id', (array)$user_ids)->where('status', 1)->pluck('id')->toArray();
$continue = true;
$nouser = intval($step['nouser']);
// 找不到匹配的办理人
if (empty($step['user_ids'])) {
if ($nouser == 0) {
$step['select_org'] = 1;
} else if ($nouser == 1) {
// 不跳过节点继续寻找下一个节点
$continue = false;
$step['hide'] = true;
} else if ($nouser == 2) {
$step['user_ids'] = [$step['nouser_user_id']];
}
}
return ['step' => $step, 'continue' => $continue];
}
/**
* 条件测试
*/
public static function testCondition($a, $b, $t) {
if($t == '==') {
return $a == $b;
}
if($t == '<>') {
return $a <> $b;
}
if($t == '>') {
return $a > $b;
}
if($t == '<') {
return $a < $b;
}
if($t == '>=') {
return $a >= $b;
}
if($t == '<=') {
return $a <= $b;
}
}
/**
* 检查转入条件
*/
public static function checkCondition($run_step, $next_steps, $gets)
{
$form_data = static::formDataCondition($gets);
$step_condition = false;
$null_condition = 0;
$next_steps_count = count($next_steps);
if ($next_steps_count > 0) {
// 流程转交条件检查
$conditions = json_decode($run_step['condition'], true);
foreach ($next_steps as $step) {
$condition = $conditions[$step['step_id']];
if (empty($condition)) {
$null_condition ++;
continue;
}
$test = static::testCheckCondition($form_data, $condition, $gets);
// 条件满足记录步骤数组
if ($test) {
$step_condition = true;
}
}
// 有一种情况,多个转入步骤都是空条件, 或单转入步骤条件为空
if ($next_steps_count == $null_condition) {
$step_condition = true;
}
}
return $step_condition;
}
/**
*
* 检查条件的表单字段
*/
public static function formDataCondition($gets)
{
$master = $gets['master'];
// 获取单据创建者ID
if ($master['created_id'] > 0) {
$created_id = $master['created_id'];
} else {
$created_id = Auth::id();
}
// 创建人
$start_user = static::getMacroUser($created_id);
// 经办人
$current_user = static::getMacroUser(Auth::id());
$form_data = [];
$form_data['[start_user_id]'] = $start_user['user_id'];
$form_data['[start_role_id]'] = $start_user['role_id'];
$form_data['[start_department_id]'] = $start_user['department_id'];
$form_data['[start_user]'] = $start_user['user_name'];
$form_data['[start_position]'] = $start_user['position_name'];
$form_data['[start_group]'] = $start_user['group_name'];
$form_data['[start_role]'] = $start_user['role_name'];
$form_data['[start_department]'] = $start_user['department_name'];
$form_data['[edit_user_id]'] = $current_user['user_id'];
$form_data['[edit_role_id]'] = $current_user['role_id'];
$form_data['[edit_department_id]'] = $current_user['department_id'];
$form_data['[edit_user]'] = $current_user['user_name'];
$form_data['[edit_position]'] = $current_user['position_name'];
$form_data['[edit_group]'] = $current_user['group_name'];
$form_data['[edit_role]'] = $current_user['role_name'];
$form_data['[edit_department]'] = $current_user['department_name'];
// $form_data['[步骤号]'] = $post['setp_id'];
// $form_data['[流程设计步骤号]'] = $gets['step_number'];
// $form_data['[公共附件名称]'] = $post['attachment'];
// $form_data['[公共附件个数]'] = $post['attachment'];
return $form_data;
}
/**
* 测试检查条件
*/
public static function testCheckCondition($form_data, $conditions, $gets)
{
// 存在条件
$wheres = [];
foreach ($conditions as $condition) {
$f = $condition['f'];
$c = $condition['c'];
$v = $condition['v'];
$t = $condition['t'];
if (isset($form_data[$f])) {
$condition['f'] = "\$form_data['".$f."']";
} else {
// 分割字段名称
list($p, $k) = explode('.', $f);
// 多行子表
$lines = $gets['models'];
// 子表处理
if(isset($lines[$p])) {
$rows = $gets[$p]['rows'];
if ($t) {
$_test = false;
// 总数
if ($t == 'count') {
$count = count($rows);
if (static::testCondition($count, $v, $c)) {
$_test = true;
}
}
// 总和
if ($t == 'sum') {
$_sum = 0;
foreach ($rows as $row) {
$_sum += $row[$k];
}
if (static::testCondition($_sum, $v, $c)) {
$_test = true;
}
}
$condition['c'] = '';
$condition['v'] = '';
if($_test) {
$condition['f'] = 'true';
} else {
$condition['f'] = 'false';
}
} else {
continue;
}
} else {
// 把变量名称作为字符串赋值
$condition['f'] = "\$gets['".$p."']['".$k."']";
}
}
unset($condition['t']);
$wheres[] = join(' ', $condition);
}
// 检查条件
$where = join(' ', $wheres);
$test = eval("return $where;");
return $test;
}
/**
* 检查转入条件
*/
public static function runCheckCondition($run_step, $next_steps, $gets)
{
$form_data = static::formDataCondition($gets);
$steps = [];
$next_steps_count = count($next_steps);
if ($next_steps_count > 0) {
// 流程转交条件检查
$conditions = json_decode($run_step['condition'], true);
foreach ($next_steps as $step) {
$condition = $conditions[$step['step_id']];
if (empty($condition)) {
$steps[] = $step;
continue;
}
// 组合条件
$test = static::testCheckCondition($form_data, $condition, $gets);
// 条件满足记录步骤数组
if ($test) {
$steps[] = $step;
}
}
}
return $steps;
}
/**
*
*/
public static function getFlowStep($steps, $step, $gets, &$ret) {
$ids = array_filter(explode(',', $step['join']));
$next_steps = [];
foreach($ids as $id) {
if (isset($steps[$id])) {
$next_steps[] = $steps[$id];
}
}
$rows = static::runCheckCondition($step, $next_steps, $gets);
foreach($rows as $row) {
$ret[$row['step_id']] = $row;
static::getFlowStep($steps, $row, $gets, $ret);
}
}
/**
* 获取流程字段的数据
*/
public static function getFlowField($run_id, $row, $flow, $steps, $step, $view, $view_step_id, $action, $permission)
{
$run_step = $steps[$view_step_id];
if(empty($run_step)) {
return;
}
$write = $permission['flow_step'][$view_step_id];
$remark = $run_step['run_remark'];
$by = '';
$line = '&nbsp;&nbsp;';
if ($run_step['run_updated_id'] > 0) {
$updated_by = get_user($run_step['run_updated_id'], 'name', false);
$by = $updated_by.' '.format_datetime($run_step['run_updated_at']);
}
if ($action == 'show' || $action == 'print') {
if ($run_step['run_updated_at'] > 0) {
if ($remark == '') {
$remark = '同意';
}
} else {
if ($write['w'] == 1) {
$remark = '';
}
}
}
if ($action == 'show') {
return '<div id="flow_step_'.$view_step_id.'">'.$remark.$line.$by.'</div>';
} elseif ($action == 'print') {
return $remark.$line.$by;
} else {
if ($write['w'] == 1) {
$required = '';
if (in_array('required', (array)$write['v'])) {
$required = 'input-required';
}
return '<textarea class="form-control input-sm '.$required.'" autocomplete="off" id="step_remark_'.$view_step_id.'" name="step_remark['.$view_step_id.']">'.$remark.'</textarea>';
} else {
return '<textarea class="form-control input-sm" autocomplete="off" id="flow_step_'.$view_step_id.'" disabled="disabled" readonly="readonly">'.$remark.$line.$by.'</textarea>';
}
}
}
/**
* 获取流程日志
*/
public static function getFlowLog($run_id, $data, $model)
{
$steps = DB::table('flow_run_step')
->whereNotIn('type', ['end'])
->where('run_id', $run_id)
->orderBy('sort', 'asc')
->get();
// 设置主表数据
$gets['master'] = $data;
$gets[$model['table']] = $data;
$step = $steps[0];
$ret = [];
$ret[$step['step_id']] = $step;
$steps = array_by($steps, 'step_id');
static::getFlowStep($steps, $step, $gets, $ret);
return $ret;
}
/**
* 获取流程日志
*/
public static function getFlowLogTpl($run_id, $data, $model, $html)
{
$steps = static::getFlowLog($run_id, $data, $model);
foreach($steps as $log) {
if ($log['option'] == 1) {
$remark = $log['remark'];
if ($remark == '') {
if ($log['run_status'] == 'next' || $log['run_status'] == 'end') {
$remark = '同意';
}
}
$updated_by = get_user($log['updated_id'], 'name', false);
$html .= '<div class="row"><div class="col-sm-12 control-text">'.$log['name'].': '.$remark.'&nbsp;&nbsp;'.$updated_by.' '.format_datetime($log['updated_at']).'</div></div>';
}
}
return $html;
}
public static function getMacroUser($user_id)
{
if (empty($user_id)) {
return null;
}
return DB::table('user')
->LeftJoin('role', 'role.id', '=', 'user.role_id')
->LeftJoin('user_group', 'user_group.id', '=', 'user.group_id')
->LeftJoin('department', 'department.id', '=', 'user.department_id')
->LeftJoin('user_position', 'user_position.id', '=', 'user.position_id')
->where('user.id', $user_id)
->first([
'user.id as user_id',
'user.group_id',
'user.department_id',
'user.role_id',
'user.position_id',
'user_position.name as position_name',
'user.name as user_name',
'role.name as role_name',
'department.name as department_name',
'user_group.name as group_name'
]);
}
public static function setSort($sorts)
{
$i = 0;
foreach ($sorts as $id) {
if ($id > 0) {
$step = Step::find($id);
if ($step['type'] == 'start') {
continue;
}
$step->sort = $i;
$i++;
$step->save();
}
}
}
public static function setFieldSort($model_id)
{
$rows = Step::where('bill_id', $model_id)
->where('type', '!=', 'end')
->orderBy('sort', 'asc')
->get();
$j = 0;
foreach ($rows as $row) {
$row->sort = $j;
$j++;
$row->save();
}
}
public static function getUser($gets, $step, $auth, $table, $data, $id)
{
$user_ids = [];
switch ($step['type']) {
// 指定办理人
case 'user':
$user_ids = explode(',', $step['type_value']);
break;
// 负责人
case 'owner':
$user_ids = [$auth->owner_id];
break;
// 指定角色办理人
case 'role':
$roles = explode(',', $step['type_value']);
$user_ids = DB::table('user')->whereIn('role_id', $roles)->pluck('id')->toArray();
break;
// 单据创建者
case 'created_id':
case 'start':
$row = DB::table($table)->find($id);
$user_ids = [$row['created_id']];
break;
// 直属领导
case 'leader':
$user_ids = [$auth->leader_id];
break;
// 部门主管
case 'manager':
$user_ids = [$auth->department->manager];
break;
// 主表字段值
case 'field':
// 字段是供应商
if ($step['type_value'] == 'supplier_id') {
$supplier = DB::table('supplier')->find($data['supplier_id']);
$user_ids = [$supplier['user_id']];
// 字段是客户
} else if ($step['type_value'] == 'customer_id') {
$customer = DB::table('customer')->find($data['customer_id']);
$user_ids = [$customer['user_id']];
} else {
$user_ids = [$data[$step['type_value']]];
}
break;
// 销售团队(1级)
case 'region1':
$customer_id = $data['customer_id'];
if ($customer_id > 0) {
$customer = DB::table('customer')->find($customer_id);
$region3 = DB::table('customer_region')->find($customer['region_id']);
$region2 = DB::table('customer_region')->find($region3['parent_id']);
$region1 = DB::table('customer_region')->find($region2['parent_id']);
$user_ids = [$region1['owner_user_id']];
}
break;
// 销售团队(2级)
case 'region2':
$customer_id = $data['customer_id'];
if ($customer_id > 0) {
$customer = DB::table('customer')->find($customer_id);
$region3 = DB::table('customer_region')->find($customer['region_id']);
$region2 = DB::table('customer_region')->find($region3['parent_id']);
$user_ids = [$region2['owner_user_id']];
}
$region_id = $data['region_id'];
if ($region_id > 0) {
$region3 = DB::table('customer_region')->find($region_id);
$region2 = DB::table('customer_region')->find($region3['parent_id']);
$user_ids = [$region2['owner_user_id']];
}
break;
// 销售团队(3级)
case 'region3':
$customer_id = $data['customer_id'];
if ($customer_id > 0) {
$customer = DB::table('customer')->find($customer_id);
$region3 = DB::table('customer_region')->find($customer['region_id']);
$user_ids = [$region3['owner_user_id']];
}
break;
// 自定义
case 'custom':
// 过滤数据
$_data = Hook::fire($table . '.onSetpUser', ['gets' => $gets, 'step' => $step, 'auth' => $auth, 'table'=> $table, 'data'=> $data, 'user_ids' => $user_ids]);
extract($_data);
break;
}
return $user_ids;
}
}