修改审批

This commit is contained in:
mzl
2025-09-18 06:46:15 +00:00
parent 8f8d07044b
commit e5441d51ae
40 changed files with 440 additions and 761 deletions
@@ -3,7 +3,7 @@ namespace app\admin\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\admin\service\ApprovalFlowsService;
use app\common\service\ApprovalFlowsService;
class ApprovalFlowsController extends BaseController
{
@@ -3,7 +3,7 @@ namespace app\admin\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\admin\service\ApprovalInstancesService;
use app\common\service\ApprovalInstancesService;
class ApprovalInstancesController extends BaseController
{
@@ -3,8 +3,7 @@ namespace app\admin\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\admin\service\ApprovalRecordsService;
use app\admin\service\SysDictService;
use app\common\service\ApprovalRecordsService;
use app\common\model\SysDictItem;
use support\Request;
@@ -31,16 +30,16 @@ class ApprovalRecordsController extends BaseController
foreach ($data['records'] as $key => &$record) {
$result = [
'id' => $record['id'],
'flows_name' => $record['approvalInstance']['flows']['name'],
'flows_name' => $record['instance']['flows']['name'],
'instance_id' => $record['instance_id'],
'biz_id' => $record['approvalInstance']['biz_id'],
'biz_desc' => '备货单【'.$record['approvalInstance']['bizInfo']['order_no'].'】',
'biz_type' => $record['approvalInstance']['flow_type'],
'biz_id' => $record['instance']['biz_id'],
'biz_desc' => '备货单【'.$record['instance']['bizInfo']['order_no'].'】',
'biz_type' => $record['instance']['flow_type'],
'initiator_name' => $record['approvalInstance']['initiator']['name'],
'initiator_avatar' => $record['approvalInstance']['initiator']['avatar'],
'initiator_name' => $record['instance']['initiator']['name'],
'initiator_avatar' => $record['instance']['initiator']['avatar'],
'approver_name' => $record['approver']['name'],
'approver_avatar' => $record['approver']['avatar'],
@@ -53,8 +52,8 @@ class ApprovalRecordsController extends BaseController
'comment' => $record['comment'],
'approved_at' => $record['approved_at'],
'finished_at' => $record['approvalInstance']['finished_at'],
'deadline_at' => $record['approvalInstance']['deadline_at'],
'finished_at' => $record['instance']['finished_at'],
'deadline_at' => $record['instance']['deadline_at'],
'created_at' => $record['created_at']
];
@@ -87,4 +86,57 @@ class ApprovalRecordsController extends BaseController
return $this->error($e->getMessage());
}
}
public function todo(Request $request)
{
try {
$raw = $this->service->serviceList($request, 'todo');
$data = $this->transformData($raw, method_exists($this, 'todoFormat')
? [$this, 'todoFormat']
: null);
return $this->success($data);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
protected function todoFormat($data)
{
if (isset($data['records']) && count($data['records']) > 0) {
foreach ($data['records'] as $key => &$record) {
$result = [
'id' => $record['id'],
'flows_name' => $record['instance']['flows']['name'],
'instance_id' => $record['instance_id'],
'biz_id' => $record['instance']['biz_id'],
'biz_desc' => '备货单号【'.$record['instance']['bizInfo']['order_no'].'】',
'biz_type' => $record['instance']['flow_type'],
'initiator_name' => $record['instance']['initiator']['name'],
'initiator_avatar' => $record['instance']['initiator']['avatar'],
'approver_name' => $record['approver']['name'],
'approver_avatar' => $record['approver']['avatar'],
'step_index' => $record['step_index'],
'action' => $record['action'],
'action_desc' => SysDictItem::where('item_value', $record['action'])->where('status', 1)->value('item_label'),
'status' => $record['status'],
'status_desc' => SysDictItem::where('item_value', $record['status'])->where('status', 1)->value('item_label'),
'comment' => $record['comment'],
'approved_at' => $record['approved_at'],
'finished_at' => $record['instance']['finished_at'],
'deadline_at' => $record['instance']['deadline_at'],
'created_at' => $record['created_at']
];
$record = $result;
}
}
return $data;
}
}
@@ -1,17 +0,0 @@
<?php
namespace app\admin\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\admin\model\ApprovalInstances;
class ApprovalInstancesLogic
{
use CrudLogicTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalInstances::class;
}
-17
View File
@@ -1,17 +0,0 @@
<?php
namespace app\admin\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\admin\model\ApprovalRecords;
class ApprovalRecordsLogic
{
use CrudLogicTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalRecords::class;
}
-54
View File
@@ -1,54 +0,0 @@
<?php
namespace app\admin\model;
use support\Model;
class ApprovalFlows extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_flows';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'name', 'type', 'steps', 'is_active', 'timeout_hours', 'timeout_action', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
protected $casts = [
'steps' => 'array',
];
}
-107
View File
@@ -1,107 +0,0 @@
<?php
namespace app\admin\model;
use app\common\model\StockOrders;
use app\common\model\User;
use support\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ApprovalInstances extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_instances';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
// protected $fillable = ['id', 'flow_type', 'biz_id', 'biz_type', 'form_data', 'initiator_id', 'status', 'current_step', 'finished_at', 'deadline_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
protected $fillable = [
'flow_type',
'biz_id',
'biz_type',
'form_data',
'initiator_id',
'status',
'current_step',
'finished_at',
'deadline_at',
];
protected $casts = [
'form_data' => 'array', // 自动转换 JSON 字段为数组
'finished_at' => 'datetime',
'deadline_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* 一个审批实例可以有多个审批记录
*/
public function approvalRecords(): HasMany
{
return $this->hasMany(ApprovalRecords::class, 'instance_id');
}
/**
* 获取当前步骤的所有审批记录(pending 状态)
*/
public function currentStepRecords()
{
return $this->approvalRecords()
->where('step_index', $this->current_step)
->where('status', 'pending');
}
public function flows()
{
return $this->belongsTo(ApprovalFlows::class, 'flow_type', 'type');
}
public function initiator()
{
return $this->belongsTo(User::class, 'initiator_id', 'id');
}
public function bizInfo()
{
return $this->hasOne(StockOrders::class, 'id', 'biz_id');
}
}
-84
View File
@@ -1,84 +0,0 @@
<?php
namespace app\admin\model;
use app\common\model\User;
use support\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ApprovalRecords extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_records';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
// protected $fillable = ['id', 'instance_id', 'approver_id', 'step_index', 'action', 'status', 'comment', 'approved_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
protected $fillable = [
'instance_id',
'approver_id',
'step_index',
'action',
'status',
'comment',
'approved_at',
];
protected $casts = [
'approved_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* 一条审批记录属于一个审批实例
*/
public function approvalInstance(): BelongsTo
{
return $this->belongsTo(ApprovalInstances::class, 'instance_id');
}
/**
* 关联审批人
*/
public function approver()
{
return $this->belongsTo(User::class, 'approver_id');
}
}
@@ -1,9 +1,9 @@
<?php
namespace app\admin\logic;
namespace app\common\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\admin\model\ApprovalFlows;
use app\common\model\ApprovalFlows;
class ApprovalFlowsLogic
{
@@ -1,9 +1,9 @@
<?php
namespace app\crm\logic;
namespace app\common\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\crm\model\ApprovalInstances;
use app\common\model\ApprovalInstances;
class ApprovalInstancesLogic
{
@@ -1,9 +1,9 @@
<?php
namespace app\crm\logic;
namespace app\common\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\crm\model\ApprovalRecords;
use app\common\model\ApprovalRecords;
class ApprovalRecordsLogic
{
@@ -1,6 +1,6 @@
<?php
namespace app\common\utils\approval\model;
namespace app\common\model;
use support\Model;
@@ -35,7 +35,7 @@ class ApprovalCcs extends Model
public $timestamps = true;
protected $dateFormat = 'U';
// protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
@@ -1,6 +1,6 @@
<?php
namespace app\crm\model;
namespace app\common\model;
use support\Model;
@@ -35,7 +35,7 @@ class ApprovalFlows extends Model
public $timestamps = true;
protected $dateFormat = 'U';
// protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
@@ -47,7 +47,6 @@ class ApprovalFlows extends Model
*/
protected $guarded = [];
protected $casts = [
'steps' => 'array',
];
@@ -1,11 +1,10 @@
<?php
namespace app\crm\model;
namespace app\common\model;
use app\common\model\StockOrders;
use app\common\model\User;
use support\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class ApprovalInstances extends Model
{
@@ -38,7 +37,7 @@ class ApprovalInstances extends Model
public $timestamps = true;
protected $dateFormat = 'U';
// protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
@@ -50,7 +49,6 @@ class ApprovalInstances extends Model
*/
protected $guarded = [];
protected $fillable = [
'flow_type',
'biz_id',
@@ -71,22 +69,9 @@ class ApprovalInstances extends Model
'updated_at' => 'datetime',
];
/**
* 一个审批实例可以有多个审批记录
*/
public function approvalRecords(): HasMany
public function records()
{
return $this->hasMany(ApprovalRecords::class, 'instance_id');
}
/**
* 获取当前步骤的所有审批记录(pending 状态)
*/
public function currentStepRecords()
{
return $this->approvalRecords()
->where('step_index', $this->current_step)
->where('status', 'pending');
return $this->hasMany(ApprovalRecords::class, 'instance_id', 'id');
}
public function flows()
@@ -99,9 +84,18 @@ class ApprovalInstances extends Model
return $this->belongsTo(User::class, 'initiator_id', 'id');
}
public function bizInfo()
{
return $this->hasOne(StockOrders::class, 'id', 'biz_id');
return $this->belongsTo(StockOrders::class, 'biz_id', 'id');
}
/**
* 获取当前步骤的所有审批记录(pending 状态)
*/
public function currentStepRecords()
{
return $this->approvalRecords()
->where('step_index', $this->current_step)
->where('status', 'pending');
}
}
@@ -1,10 +1,9 @@
<?php
namespace app\crm\model;
namespace app\common\model;
use app\common\model\User;
use support\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ApprovalRecords extends Model
{
@@ -37,12 +36,12 @@ class ApprovalRecords extends Model
public $timestamps = true;
protected $dateFormat = 'U';
// protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
// protected $fillable = ['id', 'instance_id', 'approver_id', 'step_index', 'action', 'status', 'comment', 'approved_at', 'created_at', 'updated_at'];
// protected $fillable = ['id', 'instance_id', 'approver_id', 'step_index', 'action', 'comment', 'approved_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
@@ -66,19 +65,14 @@ class ApprovalRecords extends Model
'updated_at' => 'datetime',
];
/**
* 一条审批记录属于一个审批实例
*/
public function approvalInstance(): BelongsTo
public function instance()
{
return $this->belongsTo(ApprovalInstances::class, 'instance_id');
return $this->belongsTo(ApprovalInstances::class, 'instance_id', 'id');
}
/**
* 关联审批人
*/
public function approver()
{
return $this->belongsTo(User::class, 'approver_id');
return $this->belongsTo(User::class, 'approver_id', 'id');
}
}
@@ -1,10 +1,10 @@
<?php
namespace app\admin\service;
namespace app\common\service;
use app\admin\validate\ApprovalFlowsValidate;
use app\common\validate\ApprovalFlowsValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\admin\model\ApprovalFlows;
use app\common\model\ApprovalFlows;
use support\Request;
class ApprovalFlowsService
@@ -1,10 +1,10 @@
<?php
namespace app\admin\service;
namespace app\common\service;
use app\admin\validate\ApprovalInstancesValidate;
use app\common\validate\ApprovalInstancesValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\admin\model\ApprovalInstances;
use app\common\model\ApprovalInstances;
class ApprovalInstancesService
{
@@ -1,10 +1,10 @@
<?php
namespace app\admin\service;
namespace app\common\service;
use app\admin\validate\ApprovalRecordsValidate;
use app\common\validate\ApprovalRecordsValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\admin\model\ApprovalRecords;
use app\common\model\ApprovalRecords;
use support\Request;
class ApprovalRecordsService
@@ -42,17 +42,44 @@ class ApprovalRecordsService
$config['order']['id'] = 'desc';
$config['with'] = [
'approvalInstance',
'instance',
'approver',
'approvalInstance.flows',
'approvalInstance.initiator',
'approvalInstance.bizInfo'
'instance.flows',
'instance.initiator',
'instance.bizInfo'
];
// $config['dataLimit']['type'] = 'relation';
// $config['dataLimit']['userId'] = $request->user->uid;
// $config['dataLimit']['userField'] = 'approver_id';
break;
case 'todo':
if ($p['scene'] === 'todo') {
// if (!in_array(1, $request->user->role_ids)) {
$config['where']['approver_id'] = $request->user->uid;
// }
$config['where']['status'] = 'pending';
$config['where']['instance.status'] = 'processing';
}
if ($p['scene'] === 'history') {
if (!in_array(1, $request->user->role_ids)) {
$config['where']['approver_id'] = $request->user->uid;
}
$config['where']['status'] = ['!=', 'pending'];
}
$config['order']['id'] = 'desc';
$config['with'] = [
'instance',
'approver',
'instance.flows',
'instance.initiator',
'instance.bizInfo'
];
break;
case 'show':
$config['where']['id'] = $p['id'];
break;
@@ -86,7 +86,7 @@ class MessageNotificationsService
return ['msg_id' => $msgId];
}
public function afterServiceList($data)
public function afterServiceIndex($data)
{
$data->each(function (&$item) {
$temp = explode(',', $item->recipient);
@@ -97,7 +97,7 @@ class MessageUserStatusService
}
protected function afterServiceList($res)
protected function afterServiceIndex($res)
{
$res->each(function (&$item) {
if (isset($item->message)) {
+1 -1
View File
@@ -95,7 +95,7 @@ class ResourceService
}
protected function afterServiceListAll($data)
protected function afterServiceDefault($data)
{
$data = Tree::buildMenuTreeWithReference($data->toArray());
return $data;
+6 -4
View File
@@ -28,23 +28,25 @@ class SysDictService
public static function pluckValuesByCode(string $dictCode): \Illuminate\Support\Collection
public static function pluckValuesByCode(string $dictCode): array
{
return SysDict::where('dict_code', $dictCode)
->where('status', 1)
->first()?->items()
->where('status', 1)
->orderBy('sort')
->pluck('item_value') ?? collect();
->pluck('item_value')
->toArray() ?? [];
}
public static function pluckKeyValueByCode(string $dictCode): \Illuminate\Support\Collection
public static function pluckKeyValueByCode(string $dictCode): array
{
return SysDict::where('dict_code', $dictCode)
->where('status', 1)
->first()?->items()
->where('status', 1)
->orderBy('sort')
->pluck('item_value', 'item_label') ?? collect();
->pluck('item_value', 'item_label')
->toArray() ?? [];
}
}
+36 -33
View File
@@ -27,63 +27,61 @@ trait CrudServiceTrait
}
/** 分页列表 */
public function serviceList(Request $request)
public function serviceList(Request $request, string $scene = 'index')
{
if (method_exists($this, 'complexQuery')) {
$result = $this->complexQuery($request->get());
} else {
$config = $this->buildQueryConfig($request, 'index');
$result = $this->cqyProcess(ucfirst($scene), $request);
if ($result === false) {
$config = $this->buildQueryConfig($request, $scene);
$limit = (int)$request->get('size', 15);
$page = (int)$request->get('current', 1);
$result = $this->logicList($config, $limit, $page);
}
return $this->postProcess('List', $result);
return $this->postProcess(ucfirst($scene), $result);
}
/** 全量列表 */
public function serviceListAll(Request $request)
public function serviceListAll(Request $request, string $scene = 'default')
{
if (method_exists($this, 'complexQuery')) {
$result = $this->complexQuery($request->get());
} else {
$config = $this->buildQueryConfig($request, 'default');
$result = $this->cqyProcess(ucfirst($scene), $request);
if ($result === false) {
$config = $this->buildQueryConfig($request, $scene);
$result = $this->logicListAll($config);
}
return $this->postProcess('ListAll', $result);
return $this->postProcess(ucfirst($scene), $result);
}
/** 查看单条 */
public function serviceShow(Request $request)
public function serviceShow(Request $request, string $scene = 'show')
{
$config = $this->buildQueryConfig($request, 'show');
$config = $this->buildQueryConfig($request, $scene);
$item = $this->logicShow($config);
return $this->postProcess('Show', $item);
return $this->postProcess(ucfirst($scene), $item);
}
/** 创建 */
public function serviceStore(Request $request, array $data = [])
public function serviceStore(Request $request, array $data = [], string $scene = 'store')
{
$data = $this->preProcess('Store', $data, $request);
$data = $this->preProcess(ucfirst($scene), $data, $request);
$dl = $this->getDataLimitFromRequest($request);
$created = $this->logicCreate($data, $dl);
return $this->postProcess('Store', $created);
return $this->postProcess(ucfirst($scene), $created);
}
/** 更新 */
public function serviceUpdate(Request $request, array $data = [])
public function serviceUpdate(Request $request, array $data = [], string $scene = 'update')
{
$data = $this->preProcess('Update', $data, $request);
$config = $this->buildQueryConfig($request, 'update');
$data = $this->preProcess(ucfirst($scene), $data, $request);
$config = $this->buildQueryConfig($request, $scene);
$updated = $this->logicUpdateBy($config, $data);
return $this->postProcess('Update', $data);
return $this->postProcess(ucfirst($scene), $data);
}
/** 删除 */
public function serviceDestroy(Request $request)
public function serviceDestroy(Request $request, string $scene = 'destroy')
{
$config = $this->buildQueryConfig($request, 'destroy');
$config = $this->buildQueryConfig($request, $scene);
$deleted = $this->logicDeleteBy($config);
return $this->postProcess('Destroy', $deleted);
return $this->postProcess(ucfirst($scene), $deleted);
}
/** ----------------- 公共辅助方法 ----------------- */
@@ -182,13 +180,18 @@ trait CrudServiceTrait
: $data;
}
/**
* 处理复杂查询
* 覆盖此方法,实现复杂查询逻辑
/**
* 复杂/自定义查询
*
* @param string $op 场景
* @param mixed $data 原始返回值
* @return mixed 处理后的返回值
*/
// protected function complexQuery(array $params): array
// {
// throw new BusinessException('请在子类实现 complexQuery');
// }
protected function cqyProcess(string $op, Request $request): mixed
{
$hook = "complexQuery{$op}";
return method_exists($this, $hook)
? $this->{$hook}($request)
: false;
}
}
@@ -0,0 +1,194 @@
<?php
namespace app\common\traits\crud;
use support\exception\BusinessException;
use support\Request;
/**
* Trait CrudServiceTrait
*
* 提供标准的增删改查 Service 接口,依赖 CrudLogicTrait。
* 使用此 Trait 的 Service 类,须:
* use CrudLogicTrait, CrudServiceTrait;
* protected string $modelClass = \App\common\model\YourModel::class;
*/
trait CrudServiceTrait_bak
{
use CrudLogicTrait;
/** 具体 Service 里定义:protected string $modelClass = YourModel::class; */
/**
* 获取验证器
*/
public function getValidator()
{
return $this->validator;
}
/** 分页列表 */
public function serviceList(Request $request)
{
if (method_exists($this, 'complexQuery')) {
$result = $this->complexQuery($request->get());
} else {
$config = $this->buildQueryConfig($request, 'index');
$limit = (int)$request->get('size', 15);
$page = (int)$request->get('current', 1);
$result = $this->logicList($config, $limit, $page);
}
return $this->postProcess('List', $result);
}
/** 全量列表 */
public function serviceListAll(Request $request)
{
if (method_exists($this, 'complexQuery')) {
$result = $this->complexQuery($request->get());
} else {
$config = $this->buildQueryConfig($request, 'default');
$result = $this->logicListAll($config);
}
return $this->postProcess('ListAll', $result);
}
/** 查看单条 */
public function serviceShow(Request $request)
{
$config = $this->buildQueryConfig($request, 'show');
$item = $this->logicShow($config);
return $this->postProcess('Show', $item);
}
/** 创建 */
public function serviceStore(Request $request, array $data = [])
{
$data = $this->preProcess('Store', $data, $request);
$dl = $this->getDataLimitFromRequest($request);
$created = $this->logicCreate($data, $dl);
return $this->postProcess('Store', $created);
}
/** 更新 */
public function serviceUpdate(Request $request, array $data = [])
{
$data = $this->preProcess('Update', $data, $request);
$config = $this->buildQueryConfig($request, 'update');
$updated = $this->logicUpdateBy($config, $data);
return $this->postProcess('Update', $data);
}
/** 删除 */
public function serviceDestroy(Request $request)
{
$config = $this->buildQueryConfig($request, 'destroy');
$deleted = $this->logicDeleteBy($config);
return $this->postProcess('Destroy', $deleted);
}
/** ----------------- 公共辅助方法 ----------------- */
/**
* 构造 CrudUtil 查询配置
*/
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
{
$p = $request->all();
$config = [];
$config['model'] = $this->modelClass;
switch ($scene) {
case 'default':
$config['where']['status'] = 1;
$config['order']['sort'] = 'desc';
$config['order']['id'] = 'desc';
break;
case 'index':
$config['where']['status'] = 1;
$config['order']['sort'] = 'desc';
$config['order']['id'] = 'desc';
break;
case 'show':
$config['where']['id'] = $p['id'];
$config['where']['status'] = 1;
break;
case 'store':
break;
case 'update':
$config['where']['id'] = $p['id'];
break;
case 'destroy':
$config['where']['id'] = $p['id'];
break;
}
return $config;
}
/** 解析 withFields 字符串 "rel:field,field;..." */
protected function parseWithFields(string $str): array
{
if (!$str) {
return [];
}
$out = [];
foreach (explode(';', $str) as $pair) {
[$rel, $flds] = explode(':', $pair);
$out[$rel] = explode(',', $flds);
}
return $out;
}
/** 从请求读取 dataLimitType, dataLimitField */
protected function getDataLimitFromRequest(Request $req): array
{
$type = $req->get('dataLimitType');
if (!$type) {
return [];
}
return [
'type' => $type,
'field' => $req->get('dataLimitField', 'admin_id'),
];
}
/**
* $data 前置处理
*
* @param array $data
* @param Request $request
* @return array
*/
protected function preProcess(string $op, mixed $data, Request $request): mixed
{
$hook = "beforeService{$op}";
return method_exists($this, $hook)
? $this->{$hook}($data, $request)
: $data;
}
/**
* 根据操作类型,调用对应的后置钩子
*
* @param string $op 操作:List, Show, Store, Update, Destroy
* @param mixed $data 原始返回值
* @return mixed 处理后的返回值
*/
protected function postProcess(string $op, mixed $data): mixed
{
$hook = "afterService{$op}";
return method_exists($this, $hook)
? $this->{$hook}($data)
: $data;
}
/**
* 处理复杂查询
* 覆盖此方法,实现复杂查询逻辑
*/
// protected function complexQuery(array $params): array
// {
// throw new BusinessException('请在子类实现 complexQuery');
// }
}
@@ -1,49 +0,0 @@
<?php
namespace app\common\utils\approval\model;
use support\Model;
class ApprovalFlows extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_flows';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'name', 'type', 'steps', 'is_active', 'timeout_hours', 'timeout_action', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
}
@@ -1,49 +0,0 @@
<?php
namespace app\common\utils\approval\model;
use support\Model;
class ApprovalInstances extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_instances';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'flow_type', 'biz_id', 'biz_type', 'form_data', 'initiator_id', 'status', 'current_step', 'finished_at', 'deadline_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
}
@@ -1,49 +0,0 @@
<?php
namespace app\common\utils\approval\model;
use support\Model;
class ApprovalRecords extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'approval_records';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'instance_id', 'approver_id', 'step_index', 'action', 'comment', 'approved_at', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
}
@@ -1,7 +1,6 @@
<?php
namespace app\common\utils\approval\service;
use app\common\service\MessageNotificationsService;
use support\exception\BusinessException;
use support\Db;
@@ -577,7 +576,7 @@ class ApprovalFlowService
$prefix = $isCC ? '【抄送】' : '【审批】';
$text = $map[$action] ?? $action;
$approvalType = array_flip(\app\common\service\SysDictService::pluckKeyValueByCode('approval_type')->toArray());
$approvalType = array_flip(\app\common\service\SysDictService::pluckKeyValueByCode('approval_type'));
switch ($instance->flow_type) {
case 'stock_orders': // 备货单
@@ -1,6 +1,6 @@
<?php
namespace app\admin\validate;
namespace app\common\validate;
use think\Validate;
@@ -1,6 +1,6 @@
<?php
namespace app\admin\validate;
namespace app\common\validate;
use think\Validate;
@@ -1,6 +1,6 @@
<?php
namespace app\admin\validate;
namespace app\common\validate;
use think\Validate;
-47
View File
@@ -98,53 +98,6 @@ class IndexController
}
public function test2(Request $request)
{
$where[] = ['id', '>', 141];
$list = (new \app\common\utils\MigrationResources())->getFullResourceTreeOptimized('resources', $where);
$keys = ['system_id','name','desc','type','code','parent_id','url','icon','open_type','link',
'is_hide','is_hide_tab','no_auth','is_home','instance','keep_alive','sort','status'];
foreach ($list as $key=>$item) {
$temp = [];
foreach ($item as $k=>$v) {
if (isset($item['children']) && count($item['children']) > 0) {
$temp = $item['children'];
}
if (!in_array($k, $keys)) {
unset($item[$k]);
}
$id = Db::table('resources')->insertGetId($item);
if ($temp) {
foreach ($temp as $kc=>$vc) {
foreach ($vc as $kk => $vv) {
if (!in_array($kk, $keys)) {
unset($vc[$kk]);
}
}
$vc['parent_id'] = $id;
Db::table('resources')->insert($vc);
}
}
}
}
}
public function test(Request $request)
{
// 菜单迁移
@@ -3,7 +3,7 @@ namespace app\crm\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\crm\service\ApprovalFlowsService;
use app\common\service\ApprovalFlowsService;
class ApprovalFlowsController extends BaseController
{
@@ -3,7 +3,7 @@ namespace app\crm\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\crm\service\ApprovalInstancesService;
use app\common\service\ApprovalInstancesService;
class ApprovalInstancesController extends BaseController
{
@@ -3,7 +3,7 @@ namespace app\crm\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\crm\service\ApprovalRecordsService;
use app\common\service\ApprovalRecordsService;
use app\common\model\SysDictItem;
use support\Request;
@@ -86,4 +86,58 @@ class ApprovalRecordsController extends BaseController
return $this->error($e->getMessage());
}
}
public function todo(Request $request)
{
try {
$raw = $this->service->serviceList($request, 'todo');
$data = $this->transformData($raw, method_exists($this, 'todoFormat')
? [$this, 'todoFormat']
: null);
return $this->success($data);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
protected function todoFormat($data)
{
if (isset($data['records']) && count($data['records']) > 0) {
foreach ($data['records'] as $key => &$record) {
$result = [
'id' => $record['id'],
'flows_name' => $record['approvalInstance']['flows']['name'],
'instance_id' => $record['instance_id'],
'biz_id' => $record['approvalInstance']['biz_id'],
'biz_desc' => '备货单号【'.$record['approvalInstance']['bizInfo']['order_no'].'】',
'biz_type' => $record['approvalInstance']['flow_type'],
'initiator_name' => $record['approvalInstance']['initiator']['name'],
'initiator_avatar' => $record['approvalInstance']['initiator']['avatar'],
'approver_name' => $record['approver']['name'],
'approver_avatar' => $record['approver']['avatar'],
'step_index' => $record['step_index'],
'action' => $record['action'],
'action_desc' => SysDictItem::where('item_value', $record['action'])->where('status', 1)->value('item_label'),
'status' => $record['status'],
'status_desc' => SysDictItem::where('item_value', $record['status'])->where('status', 1)->value('item_label'),
'comment' => $record['comment'],
'approved_at' => $record['approved_at'],
'finished_at' => $record['approvalInstance']['finished_at'],
'deadline_at' => $record['approvalInstance']['deadline_at'],
'created_at' => $record['created_at']
];
$record = $result;
}
}
return $data;
}
}
-17
View File
@@ -1,17 +0,0 @@
<?php
namespace app\crm\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\crm\model\ApprovalFlows;
class ApprovalFlowsLogic
{
use CrudLogicTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalFlows::class;
}
-31
View File
@@ -1,31 +0,0 @@
<?php
namespace app\crm\service;
use app\crm\validate\ApprovalFlowsValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\crm\model\ApprovalFlows;
class ApprovalFlowsService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalFlows::class;
/**
* 验证器
*/
protected $validator = ApprovalFlowsValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
}
@@ -1,31 +0,0 @@
<?php
namespace app\crm\service;
use app\crm\validate\ApprovalInstancesValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\crm\model\ApprovalInstances;
class ApprovalInstancesService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalInstances::class;
/**
* 验证器
*/
protected $validator = ApprovalInstancesValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
}
@@ -1,91 +0,0 @@
<?php
namespace app\crm\service;
use app\crm\validate\ApprovalRecordsValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\crm\model\ApprovalRecords;
use support\Request;
class ApprovalRecordsService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = ApprovalRecords::class;
/**
* 验证器
*/
protected $validator = ApprovalRecordsValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
{
$p = $request->all();
$config = [];
$config['model'] = $this->modelClass;
switch ($scene) {
case 'index':
$config['order']['id'] = 'desc';
$config['with'] = [
'approvalInstance',
'approver',
'approvalInstance.flows',
'approvalInstance.initiator',
'approvalInstance.bizInfo'
];
$config['dataLimit']['type'] = 'relation';
$config['dataLimit']['userId'] = $request->user->uid;
$config['dataLimit']['userField'] = 'approver_id';
break;
case 'show':
$config['where']['id'] = $p['id'];
break;
case 'store':
break;
case 'update':
$config['where']['id'] = $p['id'];
break;
case 'destroy':
$config['where']['id'] = $p['id'];
break;
case 'logs':
$config['where']['instance_id'] = $p['instance_id'];
$config['order']['id'] = 'desc';
break;
}
return $config;
}
public function serviceApprove(Request $request)
{
$param = $request->all();
$appro = new \app\common\utils\approval\service\ApprovalFlowService();
return $appro->approve($param['instance_id'], $request->user->uid, $param['action'], $param['comment']);
}
public function serviceLogs(Request $request)
{
$config = $this->buildQueryConfig($request, 'logs');
$item = $this->logicListAll($config);
return $this->postProcess('Logs', $item);
}
}
+4
View File
@@ -305,6 +305,8 @@ Route::group('/admin', function () {
Route::any('/list', [app\admin\controller\ApprovalRecordsController::class, 'index']);
Route::any('/logs', [app\admin\controller\ApprovalRecordsController::class, 'logs']);
Route::any('/action', [app\admin\controller\ApprovalRecordsController::class, 'approve']);
Route::any('/todo', [app\admin\controller\ApprovalRecordsController::class, 'todo']);
});
Route::group('/stock/order', function () {
@@ -395,6 +397,8 @@ Route::group('/crm', function () {
Route::any('/list', [app\crm\controller\ApprovalRecordsController::class, 'index']);
Route::any('/logs', [app\crm\controller\ApprovalRecordsController::class, 'logs']);
Route::any('/action', [app\crm\controller\ApprovalRecordsController::class, 'approve']);
Route::any('/todo', [app\admin\controller\ApprovalRecordsController::class, 'todo']);
});
// 汽车颜色