feat: 实现默认审批人和抄送人功能

- 后端新增 getDefaultApprovers 接口,从审批流程配置中获取默认审批人和抄送人
- 前端申请页面加载时自动获取并显示默认审批人和抄送人
- 添加默认审批流程配置:1个审批人(闫继光) + 2个抄送人(孟启、程丽敏)
- 移除后端 support 目录下的自定义 Db 和 Model 类,使用 Webman 官方实现
- 前端选择页面优化:优先从 sessionStorage 恢复,否则加载后端默认配置

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-25 18:54:38 +08:00
parent e3e2843835
commit 3968e94195
10 changed files with 184 additions and 117 deletions
@@ -205,4 +205,19 @@ class BusinessTripController extends BaseController
return $this->error($e->getMessage());
}
}
/**
* 获取默认审批人和抄送人
*/
public function getDefaultApprovers(Request $request): Response
{
$userId = $this->getUserId($request);
try {
$result = $this->service->getDefaultApprovers($userId);
return $this->success($result);
} catch (\Exception $e) {
return $this->error($e->getMessage());
}
}
}
@@ -457,4 +457,71 @@ class BusinessTripService
return $businessTrip->fresh(['itineraries', 'approvalOrder']);
});
}
/**
* 获取默认审批人和抄送人
* 从审批流程配置表中获取
*/
public function getDefaultApprovers(int $userId): array
{
// 获取出差审批流程
$flow = ApprovalFlow::where('business_type', 'business_trip')
->where('status', 1)
->first();
if (!$flow) {
return [
'approvers' => [],
'cc_users' => [],
];
}
// 获取流程节点
$nodes = ApprovalNode::where('flow_id', $flow->id)
->orderBy('order')
->get();
$approvers = [];
$ccUsers = [];
foreach ($nodes as $node) {
$nodeApprovers = $node->approvers ?? [];
if (empty($nodeApprovers)) {
continue;
}
// 根据节点类型获取用户信息
$users = User::whereIn('id', $nodeApprovers)
->where('status', 1)
->get();
$userList = [];
foreach ($nodeApprovers as $userId) {
$user = $users->firstWhere('id', $userId);
if ($user) {
$userList[] = [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar,
'position' => $user->position,
];
}
}
// 审批节点(approver, and_approve, or_approve)作为审批人
if ($node->isApprovalNode()) {
$approvers = array_merge($approvers, $userList);
}
// 通知节点(notify)作为抄送人
elseif ($node->type === ApprovalNode::TYPE_NOTIFY) {
$ccUsers = array_merge($ccUsers, $userList);
}
}
return [
'approvers' => $approvers,
'cc_users' => $ccUsers,
];
}
}
+1
View File
@@ -34,6 +34,7 @@ Route::group('/api/v1/approval', function () {
Route::group('/api/v1/business-trip', function () {
Route::get('/list', [app\controller\BusinessTripController::class, 'list']);
Route::get('/detail/{id}', [app\controller\BusinessTripController::class, 'detail']);
Route::get('/default-approvers', [app\controller\BusinessTripController::class, 'getDefaultApprovers']);
Route::post('/create', [app\controller\BusinessTripController::class, 'create']);
Route::post('/update/{id}', [app\controller\BusinessTripController::class, 'update']);
Route::post('/submit/{id}', [app\controller\BusinessTripController::class, 'submit']);
@@ -0,0 +1,24 @@
-- 添加默认出差审批流程节点
-- 1个审批人 + 2个抄送人
USE xserver;
-- 清空 business_trip 流程的现有节点
DELETE FROM approval_node WHERE flow_id = 2;
-- 添加审批节点(用户ID 2: 闫继光)
INSERT INTO approval_node (flow_id, type, name, `order`, approvers) VALUES
(2, "approver", "主管审批", 1, '[2]');
-- 添加抄送节点(用户ID 3: 孟启, 5: 程丽敏)
INSERT INTO approval_node (flow_id, type, name, `order`, approvers) VALUES
(2, "notify", "抄送人-孟启", 2, '[3]'),
(2, "notify", "抄送人-程丽敏", 3, '[5]');
-- 验证结果
SELECT "=== 默认审批流程节点 ===" AS "";
SELECT an.id, an.type, an.name, an.`order`, an.approvers, u.name AS approver_name
FROM approval_node an
LEFT JOIN users u ON JSON_CONTAINS(an.approvers, CAST(u.id AS JSON))
WHERE an.flow_id = 2
ORDER BY an.`order`;
-16
View File
@@ -1,16 +0,0 @@
<?php
namespace support;
use Webman\App;
use Workerman\Worker;
class Bootstrap
{
public static function start(?Worker $worker): void
{
// 应用启动时的初始化
error_reporting(E_ALL);
ini_set('display_errors', 'on');
}
}
-77
View File
@@ -1,77 +0,0 @@
<?php
namespace support;
use Illuminate\Database\Capsule\Manager as Capsule;
class Db
{
/**
* @var Capsule
*/
protected static $capsule = null;
/**
* 初始化
*/
public static function init(): void
{
if (self::$capsule !== null) {
return;
}
$config = config('database');
$connections = $config['connections'] ?? [];
self::$capsule = new Capsule();
foreach ($connections as $name => $connection) {
self::$capsule->addConnection($connection, $name);
}
self::$capsule->setAsGlobal();
self::$capsule->bootEloquent();
if ($default = $config['default'] ?? null) {
self::$capsule->getDatabaseManager()->setDefaultConnection($default);
}
}
/**
* 获取连接
*/
public static function connection(?string $name = null): \Illuminate\Database\Connection
{
if (self::$capsule === null) {
self::init();
}
return self::$capsule->connection($name);
}
/**
* 获取表查询构造器
*/
public static function table(string $table, ?string $connection = null): \Illuminate\Database\Query\Builder
{
return self::connection($connection)->table($table);
}
/**
* 原始SQL表达式
*/
public static function raw(string $value): \Illuminate\Database\Query\Expression
{
return self::connection()->raw($value);
}
/**
* 获取 Capsule 实例
*/
public static function getCapsule(): Capsule
{
if (self::$capsule === null) {
self::init();
}
return self::$capsule;
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
namespace support;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
/**
* 获取数据库连接
*/
public function getConnection()
{
return Db::connection($this->getConnectionName());
}
}