Files
fdesk/app/common/service/InvRequisitionApproveService.php
T
2026-02-06 13:24:17 +08:00

253 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\common\service;
use app\common\model\User;
use app\common\validate\InvRequisitionApproveValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\common\model\InvRequisitionApprove;
use support\Db;
use support\exception\BusinessException;
class InvRequisitionApproveService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = InvRequisitionApprove::class;
/**
* 验证器
*/
protected $validator = InvRequisitionApproveValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
/**
* @param string $flowType
* @param string $bizType
* @param string $bizId
* @param array $formData ['manage_user_id'=>23]//物品管理员
* @param int $initiatorId //申请人id
* @return array
*/
public function start(string $flowType, string $bizType, string $bizId, array $formData, int $initiatorId): array
{
return Db::transaction(function () use ($flowType, $bizType, $bizId, $formData, $initiatorId) {
$flow = Db::table('approval_flows')->where('type', $flowType)->where('is_active', 1)->first();
if (!$flow) throw new BusinessException("审批流程未找到或已停用: {$flowType}");
$steps = json_decode($flow->steps, true);
if (!is_array($steps) || empty($steps)) throw new BusinessException("流程步骤配置错误");
// 找首个有效步骤索引(考虑条件)
$firstIndex = $this->getNextStepIndex($steps, $formData, -1);
if ($firstIndex === null) throw new BusinessException("未找到可执行的审批步骤");
$firstStep = $steps[$firstIndex];
//$now = date('Y-m-d H:i:s');
$now = time();
$service = new \app\common\utils\approval\service\ApprovalFlowService();
// 解析首步审批人(支持 role_id 或 roles.name)
$instance = (object)[
'initiator_id' => $initiatorId,
'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
];
$approverIds = $service->StetApprovers($firstStep, $instance, true);
if(empty($approverIds)){
throw new BusinessException('未解析到任何审批人');
}
$uid = array_shift($approverIds);
$approver = User::where('id', $uid)->first();
$approveId = Db::table('inv_requisition_approve')->insertGetId([
'requisition_id' => $bizId, //申请单ID
'node_type' => $bizType,
'approver_id' => $approver->id,
'approver_name' => $approver->name,
'action' => 0,
'comment' => '',
'created_at' => $now,
'updated_at' => $now,
]);
// foreach ($approverIds as $uid) {
// $this->insertApprovalRecord($instance, $firstIndex, $uid);
// }
return ['instance_id' => $approveId];
});
}
/** 执行审批 */
public function approve(int $requisitionId, int $approverId, int $uid, string $action, string $comment = '')
{
if (!in_array($action, ['1','2'], true)) { //审批动作:1通过 2驳回
throw new BusinessException("无效的审批操作");
}
return Db::transaction(function () use ($requisitionId, $approverId, $uid, $action, $comment) {
// $instance = Db::table('approval_instances')->where('id', $instanceId)->lockForUpdate()->first();
$requisition = Db::table('inv_requisition')->where('id', $requisitionId)->lockForUpdate()->first();
if (!$requisition) throw new BusinessException("审批实例未找到");
if ($requisition->status !== 10 && $requisition->status !== 11) {
return ['status' => 'noop', 'msg' => '实例未处理'];
}
//审批流程
$flow = Db::table('approval_flows')->where('type', 'inv_requisition')->first();
if (!$flow) throw new BusinessException("审批流程定义未找到");
$steps = json_decode($flow->steps, true);
//$idx = (int)$requisition->current_step;
//$step = $steps[$idx] ?? null;
//if (!$step) throw new BusinessException("当前步骤配置错误");
// 找到该用户在本步的 pending 记录(加锁)
$pendingRecord = Db::table('inv_requisition_approve')
->where('requisition_id', $requisitionId)
->where('id', $approverId)
->where('action', 0)
->lockForUpdate()
->first();
if (!$pendingRecord) {
// 已处理过?
$anyRecord = Db::table('inv_requisition_approve')
->where('requisition_id', $requisitionId)
->where('id', $approverId)
->first();
if ($anyRecord && $anyRecord->action > 0) {
return ['status' => 'noop', 'msg' => '已处理'];
}
// 步骤已推进
// if ((int)$requisition->current_step !== $idx) {
// return ['status' => 'noop', 'msg' => '非当前审批'];
// }
return ['status' => 'noop', 'msg' => '无待处理记录'];
}
// else{
// if ($pendingRecord->approver_id == $uid) {
// return ['status' => 'noop', 'msg' => '无审核权限'];
// }
// }
$now = time();
// 1) 更新当前人的审批记录
Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([
'action' => $action,
'comment' => $comment,
'action_at' => $now,
'updated_at' => $now,
]);
// 2) 已通过步骤与总步数相等则结束审核流程
$pass = Db::table('inv_requisition_approve')
->where('requisition_id', $requisitionId)
->where('action', 1)
->count();
if($action == 1){
if(count($steps) == $pass){
$requisitionItem = Db::table('inv_requisition_item')
->where('requisition_id', $requisition->id)
->where('is_consumable_snap', 0)
->get();
if($requisitionItem){
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>12]);
}else{
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>19]);
}
// $requisition->status = 12;
// $requisition->save();
return ['status' => 'complete', 'msg' => '已通过'];
}
}
// 3) 拒绝 => 结束
if($action == 2){
Db::table('inv_requisition_approve')->where('id', $pendingRecord->id)->update([
'action' => $action,
'comment' => $comment,
'approved_at' => $now,
'updated_at' => $now,
]);
if(count($steps) == $pass){
Db::table('inv_requisition')->where('id', $requisition->id)->update(['status'=>12]);
// $requisition->status = 13;
// $requisition->save();
return ['status' => 'complete', 'msg' => '拒绝'];
}
}
// 4) 通过 => 进入下一步或结束
$requisitionItem = Db::table('inv_requisition_item')->where('requisition_id', $requisitionId)->first();
$item_id = Db::table('inv_item')->where('id', $requisitionItem->item_id)->first();
$formData = ['manage_user_id'=>$item_id->manage_user_id];
$nextIndex = $pass;
$nextStep = $steps[$nextIndex];
$service = new \app\common\utils\approval\service\ApprovalFlowService();
$instance = (object)[
'initiator_id' => $requisition->applicant_id, //申请人id
'form_data'=>json_encode($formData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
];
$approverIds = $service->StetApprovers($nextStep, $instance, true);
// if($approverIds == "manage_user_id"){ //物品管理人审核步骤查询管理人
// $requisitionItem = Db::table('inv_requisition_item')->where('id', $requisitionId)->first();
// $invItem = Db::table('inv_requisition_item')->where('id', $requisitionItem->item_id)->first();
//
// if(empty($invItem)){
// return ['status' => 'noop', 'msg' => '未查询到物品管理人'];
// }
// $approverIds = [$invItem->manage_user_id];
// }
$approver = User::where('id', array_pop($approverIds))->first();
Db::table('inv_requisition_approve')->insertGetId([
'requisition_id' => $requisitionId, //申请单ID
'node_type' => $nextStep['approvers'][0]['value'],
'approver_id' => $approver->id,
'approver_name' => $approver->name,
'action' => 0,
'comment' => '',
'created_at' => $now,
'updated_at' => $now,
]);;
});
}
// public function insertApprovalRecord()
// {
// }
/** 获取下一个有效步骤索引 */
private function getNextStepIndex(array $steps, array $formData, int $currentStepIndex): ?int
{
for ($i = $currentStepIndex + 1; $i < count($steps); $i++) {
$s = $steps[$i];
if (empty($s['condition'])) {
return $i;
}
}
return null;
}
}