Files
yuezi-saas/backend/app/Http/Controllers/Admin/Office/ApprovalController.php
T
li c778639f05 fix: 修复列表筛选空参与树数据展示
将后端 status/audit_status 筛选从 has() 改为 filled(),避免空字符串导致列表被误筛空;修复预定 status=0 筛选失效;前端兼容财务分类树形返回与菜单/字典数组返回,解决新增成功但列表空。
2026-03-15 00:06:11 +08:00

216 lines
7.3 KiB
PHP

<?php
namespace App\Http\Controllers\Admin\Office;
use App\Http\Controllers\Controller;
use App\Models\Office\Approval;
use App\Models\Office\ApprovalNode;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class ApprovalController extends Controller
{
public function index(Request $request): JsonResponse
{
$query = Approval::query()->with(['template', 'applicant']);
$query->when($request->filled('status'), fn($q) => $q->where('status', $request->status));
$query->when($request->applicant_id, fn($q, $v) => $q->where('applicant_id', $v));
return $this->paginate($query->latest()->paginate($request->input('per_page', 15)));
}
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'template_id' => 'nullable|exists:approval_templates,id',
'form_data' => 'nullable|array',
'related_type' => 'nullable|string|max:50',
'related_id' => 'nullable|integer',
]);
$validated['applicant_id'] = auth()->id();
$validated['status'] = 0;
$validated['current_node'] = 1;
$approval = null;
DB::transaction(function () use ($validated, &$approval) {
$approval = Approval::create($validated);
// 根据模板 flow_nodes 自动创建多级审批节点
if ($approval->template_id && $approval->template) {
$flowNodes = $approval->template->flow_nodes ?? [];
foreach ($flowNodes as $node) {
$level = $node['level'] ?? 1;
$role = $node['role'] ?? null;
$label = $node['label'] ?? "第{$level}级审批";
// 按 role 找同门店下首个匹配用户
$approverId = null;
if ($role) {
$approverId = User::whereHas('roles', fn($q) => $q->where('slug', $role))
->where('store_id', $approval->store_id)
->value('id');
}
ApprovalNode::create([
'approval_id' => $approval->id,
'node_order' => $level,
'node_label' => $label,
'role' => $role,
'approver_id' => $approverId,
'action' => 0,
]);
}
} else {
// 无模板:创建单一审批节点
ApprovalNode::create([
'approval_id' => $approval->id,
'node_order' => 1,
'node_label' => '审批',
'action' => 0,
]);
}
});
return $this->success($approval->load(['template', 'applicant', 'nodes']));
}
public function show(Approval $approval): JsonResponse
{
return $this->success($approval->load(['template', 'applicant', 'nodes.approver']));
}
public function update(Request $request, Approval $approval): JsonResponse
{
if ($approval->status > 1) {
return $this->error('该审批已完结,无法修改', 40001);
}
$validated = $request->validate([
'title' => 'sometimes|string|max:255',
'form_data' => 'nullable|array',
]);
$approval->update($validated);
return $this->success($approval);
}
public function destroy(Approval $approval): JsonResponse
{
if ($approval->status > 1) {
return $this->error('该审批已完结,无法删除', 40001);
}
$approval->delete();
return $this->success(null);
}
public function approve(Request $request, Approval $approval): JsonResponse
{
if ($approval->status >= 2) {
return $this->error('该审批已完结', 40001);
}
$currentUser = auth()->user();
$userRoles = $currentUser->roles()->pluck('slug')->toArray();
// 当前节点匹配:approver_id 精确匹配 或 role 匹配当前用户角色
$node = $approval->nodes()
->where('node_order', $approval->current_node)
->where('action', 0)
->where(function ($q) use ($currentUser, $userRoles) {
$q->where('approver_id', $currentUser->id)
->orWhereIn('role', $userRoles)
->orWhereNull('approver_id'); // 无指定审批人时任何人可审
})
->first();
if (!$node) {
return $this->error('无待处理的审批节点或您无权审批此节点', 40001);
}
$validated = $request->validate([
'comment' => 'nullable|string|max:255',
]);
$node->update([
'action' => 1,
'approver_id' => $currentUser->id,
'comment' => $validated['comment'] ?? null,
'acted_at' => now(),
]);
// 检查是否还有下一节点
$hasNext = $approval->nodes()
->where('node_order', '>', $approval->current_node)
->where('action', 0)
->exists();
if ($hasNext) {
$approval->update([
'status' => 1, // 审批中
'current_node' => $approval->current_node + 1,
]);
} else {
$approval->update(['status' => 2]); // 已通过
}
return $this->success($approval->load(['nodes.approver']));
}
public function reject(Request $request, Approval $approval): JsonResponse
{
if ($approval->status >= 2) {
return $this->error('该审批已完结', 40001);
}
$currentUser = auth()->user();
$userRoles = $currentUser->roles()->pluck('slug')->toArray();
$node = $approval->nodes()
->where('node_order', $approval->current_node)
->where('action', 0)
->where(function ($q) use ($currentUser, $userRoles) {
$q->where('approver_id', $currentUser->id)
->orWhereIn('role', $userRoles)
->orWhereNull('approver_id');
})
->first();
if (!$node) {
return $this->error('无待处理的审批节点或您无权操作', 40001);
}
$validated = $request->validate([
'comment' => 'nullable|string|max:255',
]);
$node->update([
'action' => 2,
'approver_id' => $currentUser->id,
'comment' => $validated['comment'] ?? null,
'acted_at' => now(),
]);
$approval->update(['status' => 3]); // 已驳回
return $this->success($approval->load(['nodes.approver']));
}
public function withdraw(Approval $approval): JsonResponse
{
if ($approval->status > 1) {
return $this->error('该审批已完结,无法撤回', 40001);
}
if ($approval->applicant_id !== auth()->id()) {
return $this->error('只能撤回自己发起的审批', 40001);
}
$approval->update(['status' => 4]);
return $this->success($approval);
}
}