admin 重写审核流程

main
panliang 2024-04-03 18:54:01 +08:00
parent dcdaa909c7
commit d591be918b
31 changed files with 289 additions and 295 deletions

View File

@ -61,16 +61,16 @@ class HolidayController extends AdminController
amisMake()->TableColumn()->name('reason')->label(__('holiday_apply.reason')), amisMake()->TableColumn()->name('reason')->label(__('holiday_apply.reason')),
amisMake()->TableColumn()->name('start_at')->label(__('holiday_apply.start_at')), amisMake()->TableColumn()->name('start_at')->label(__('holiday_apply.start_at')),
amisMake()->TableColumn()->name('end_at')->label(__('holiday_apply.end_at')), amisMake()->TableColumn()->name('end_at')->label(__('holiday_apply.end_at')),
amisMake()->TableColumn()->name('check_status')->label(__('holiday_apply.check_status'))->set('type', 'mapping')->map(CheckStatus::options()), amisMake()->TableColumn()->name('workflow.check_status')->label(__('holiday_apply.check_status'))->set('type', 'mapping')->map(CheckStatus::options()),
amisMake()->TableColumn()->name('created_at')->label(__('holiday_apply.created_at')), amisMake()->TableColumn()->name('created_at')->label(__('holiday_apply.created_at')),
$this->rowActions([ $this->rowActions([
$this->rowShowButton()->visible(Admin::user()->can('admin.hr.holiday.view')), $this->rowShowButton()->visible(Admin::user()->can('admin.hr.holiday.view')),
$this->rowEditTypeButton('drawer', 'xl') $this->rowEditTypeButton('drawer', 'xl')
->visible(Admin::user()->can('admin.hr.holiday.update')) ->visible(Admin::user()->can('admin.hr.holiday.update'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->rowDeleteButton() $this->rowDeleteButton()
->visible(Admin::user()->can('admin.hr.holiday.delete')) ->visible(Admin::user()->can('admin.hr.holiday.delete'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->applyAction(), $this->applyAction(),
$this->cancelAction(), $this->cancelAction(),
]), ]),
@ -108,7 +108,6 @@ class HolidayController extends AdminController
public function detail(): Form public function detail(): Form
{ {
$subjectType = $this->getMorphAlias();
$detail = amisMake()->Property()->items([ $detail = amisMake()->Property()->items([
['label' => __('holiday_apply.store_id'), 'content' => '${store.title}'], ['label' => __('holiday_apply.store_id'), 'content' => '${store.title}'],
['label' => __('holiday_apply.employee_id'), 'content' => '${employee.name}'], ['label' => __('holiday_apply.employee_id'), 'content' => '${employee.name}'],
@ -116,19 +115,14 @@ class HolidayController extends AdminController
['label' => __('holiday_apply.date'), 'content' => '${start_at} ${end_at}'], ['label' => __('holiday_apply.date'), 'content' => '${start_at} ${end_at}'],
['label' => __('holiday_apply.reason'), 'content' => '${reason}'], ['label' => __('holiday_apply.reason'), 'content' => '${reason}'],
['label' => __('holiday_apply.created_at'), 'content' => '${created_at}'], ['label' => __('holiday_apply.created_at'), 'content' => '${created_at}'],
['label' => __('holiday_apply.check_status'), 'content' => amisMake()->Mapping()->name('check_status')->map(CheckStatus::options())], ['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
['label' => __('holiday_apply.checked_at'), 'content' => '${checked_at}'], ['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
['label' => __('holiday_apply.check_remarks'), 'content' => '${check_remarks}'], ['label' => __('workflow_log.remarks'), 'content' => '${workflow.check_remarks}'],
]); ]);
$table = amisMake()->Service() $table = amisMake()->Service()
->id('holiday-checklog-table') ->id('holiday-checklog-table')
->initFetch(false) ->initFetch(false)
->api( ->api(admin_url('api/workflow/logs') . '?id=${workflow.id}')
amisMake()->BaseApi()->method('get')->url(admin_url('api/workflow/logs'))->data([
'subject_type' => $subjectType,
'subject_id' => '${id}',
])
)
->body( ->body(
amisMake()->Table()->columnsTogglable(false)->itemActions([ amisMake()->Table()->columnsTogglable(false)->itemActions([
$this->succesAction()->reload('holiday-detail'), $this->succesAction()->reload('holiday-detail'),
@ -150,9 +144,4 @@ class HolidayController extends AdminController
] ]
])->body([$detail, amisMake()->Divider(), $table]); ])->body([$detail, amisMake()->Divider(), $table]);
} }
public function getMorphAlias()
{
return (new HolidayApply)->getMorphClass();
}
} }

View File

@ -55,16 +55,16 @@ class OfficalBusinessController extends AdminController
amisMake()->TableColumn()->name('end_at')->label(__('offical_business.date')), amisMake()->TableColumn()->name('end_at')->label(__('offical_business.date')),
amisMake()->TableColumn()->name('address')->label(__('offical_business.address')), amisMake()->TableColumn()->name('address')->label(__('offical_business.address')),
amisMake()->TableColumn()->name('reason')->label(__('offical_business.reason')), amisMake()->TableColumn()->name('reason')->label(__('offical_business.reason')),
amisMake()->TableColumn()->name('check_status')->label(__('offical_business.check_status'))->set('type', 'mapping')->map(CheckStatus::options()), amisMake()->TableColumn()->name('workflow.check_status')->label(__('workflow_log.check_status'))->set('type', 'mapping')->map(CheckStatus::options()),
amisMake()->TableColumn()->name('created_at')->label(__('offical_business.created_at')), amisMake()->TableColumn()->name('created_at')->label(__('offical_business.created_at')),
$this->rowActions([ $this->rowActions([
$this->rowShowButton()->visible(Admin::user()->can('admin.hr.business.view')), $this->rowShowButton()->visible(Admin::user()->can('admin.hr.business.view')),
$this->rowEditTypeButton('drawer', 'xl') $this->rowEditTypeButton('drawer', 'xl')
->visible(Admin::user()->can('admin.hr.business.update')) ->visible(Admin::user()->can('admin.hr.business.update'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->rowDeleteButton() $this->rowDeleteButton()
->visible(Admin::user()->can('admin.hr.business.delete')) ->visible(Admin::user()->can('admin.hr.business.delete'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->applyAction(), $this->applyAction(),
$this->cancelAction(), $this->cancelAction(),
]), ]),
@ -95,7 +95,6 @@ class OfficalBusinessController extends AdminController
public function detail(): Form public function detail(): Form
{ {
$subjectType = $this->getMorphAlias();
$detail = amisMake()->Property()->items([ $detail = amisMake()->Property()->items([
['label' => __('offical_business.store_id'), 'content' => '${store.title}'], ['label' => __('offical_business.store_id'), 'content' => '${store.title}'],
['label' => __('offical_business.employee_id'), 'content' => '${employee.name}'], ['label' => __('offical_business.employee_id'), 'content' => '${employee.name}'],
@ -103,19 +102,14 @@ class OfficalBusinessController extends AdminController
['label' => __('offical_business.address'), 'content' => '${address}'], ['label' => __('offical_business.address'), 'content' => '${address}'],
['label' => __('offical_business.reason'), 'content' => '${reason}'], ['label' => __('offical_business.reason'), 'content' => '${reason}'],
['label' => __('offical_business.created_at'), 'content' => '${created_at}'], ['label' => __('offical_business.created_at'), 'content' => '${created_at}'],
['label' => __('offical_business.check_status'), 'content' => amisMake()->Mapping()->name('check_status')->map(CheckStatus::options())], ['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
['label' => __('offical_business.checked_at'), 'content' => '${checked_at}'], ['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
['label' => __('offical_business.check_remarks'), 'content' => '${check_remarks}'], ['label' => __('workflow_log.remarks'), 'content' => '${workflow.check_remarks}'],
]); ]);
$table = amisMake()->Service() $table = amisMake()->Service()
->id('offical-business-checklog-table') ->id('offical-business-checklog-table')
->initFetch(false) ->initFetch(false)
->api( ->api(admin_url('api/workflow/logs') . '?id=${workflow.id}')
amisMake()->BaseApi()->method('get')->url(admin_url('api/workflow/logs'))->data([
'subject_type' => $subjectType,
'subject_id' => '${id}',
])
)
->body( ->body(
amisMake()->Table()->columnsTogglable(false)->itemActions([ amisMake()->Table()->columnsTogglable(false)->itemActions([
$this->succesAction()->reload('offical-business-detail'), $this->succesAction()->reload('offical-business-detail'),
@ -137,9 +131,4 @@ class OfficalBusinessController extends AdminController
] ]
])->body([$detail, amisMake()->Divider(), $table]); ])->body([$detail, amisMake()->Divider(), $table]);
} }
public function getMorphAlias()
{
return (new OfficalBusiness)->getMorphClass();
}
} }

View File

@ -56,16 +56,16 @@ class OvertimeController extends AdminController
amisMake()->TableColumn()->name('employee.name')->label(__('overtime_apply.employee_id')), amisMake()->TableColumn()->name('employee.name')->label(__('overtime_apply.employee_id')),
amisMake()->TableColumn()->name('date')->label(__('overtime_apply.date')), amisMake()->TableColumn()->name('date')->label(__('overtime_apply.date')),
amisMake()->TableColumn()->name('hours')->label(__('overtime_apply.hours')), amisMake()->TableColumn()->name('hours')->label(__('overtime_apply.hours')),
amisMake()->TableColumn()->name('check_status')->label(__('overtime_apply.check_status'))->set('type', 'mapping')->map(CheckStatus::options()), amisMake()->TableColumn()->name('workflow.check_status')->label(__('workflow_log.check_status'))->set('type', 'mapping')->map(CheckStatus::options()),
amisMake()->TableColumn()->name('created_at')->label(__('overtime_apply.created_at')), amisMake()->TableColumn()->name('created_at')->label(__('overtime_apply.created_at')),
$this->rowActions([ $this->rowActions([
$this->rowShowButton()->visible(Admin::user()->can('admin.hr.overtime.view')), $this->rowShowButton()->visible(Admin::user()->can('admin.hr.overtime.view')),
$this->rowEditTypeButton('drawer', 'xl') $this->rowEditTypeButton('drawer', 'xl')
->visible(Admin::user()->can('admin.hr.overtime.update')) ->visible(Admin::user()->can('admin.hr.overtime.update'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->rowDeleteButton() $this->rowDeleteButton()
->visible(Admin::user()->can('admin.hr.overtime.delete')) ->visible(Admin::user()->can('admin.hr.overtime.delete'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->applyAction(), $this->applyAction(),
$this->cancelAction(), $this->cancelAction(),
]), ]),
@ -95,7 +95,6 @@ class OvertimeController extends AdminController
public function detail(): Form public function detail(): Form
{ {
$subjectType = $this->getMorphAlias();
$detail = amisMake()->Property()->items([ $detail = amisMake()->Property()->items([
['label' => __('overtime_apply.store_id'), 'content' => '${store.title}'], ['label' => __('overtime_apply.store_id'), 'content' => '${store.title}'],
['label' => __('overtime_apply.employee_id'), 'content' => '${employee.name}'], ['label' => __('overtime_apply.employee_id'), 'content' => '${employee.name}'],
@ -105,19 +104,14 @@ class OvertimeController extends AdminController
['label' => __('overtime_apply.hours'), 'content' => '${hours}'], ['label' => __('overtime_apply.hours'), 'content' => '${hours}'],
['label' => __('overtime_apply.created_at'), 'content' => '${created_at}'], ['label' => __('overtime_apply.created_at'), 'content' => '${created_at}'],
['label' => __('overtime_apply.reason'), 'content' => '${reason}', 'span' => 2], ['label' => __('overtime_apply.reason'), 'content' => '${reason}', 'span' => 2],
['label' => __('overtime_apply.check_status'), 'content' => amisMake()->Mapping()->name('check_status')->map(CheckStatus::options())], ['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
['label' => __('overtime_apply.checked_at'), 'content' => '${checked_at}'], ['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
['label' => __('overtime_apply.check_remarks'), 'content' => '${check_remarks}'], ['label' => __('workflow_log.remarks'), 'content' => '${workflow.check_remarks}'],
]); ]);
$table = amisMake()->Service() $table = amisMake()->Service()
->id('overtime-checklog-table') ->id('overtime-checklog-table')
->initFetch(false) ->initFetch(false)
->api( ->api(admin_url('api/workflow/logs') . '?id=${workflow.id}')
amisMake()->BaseApi()->method('get')->url(admin_url('api/workflow/logs'))->data([
'subject_type' => $subjectType,
'subject_id' => '${id}',
])
)
->body( ->body(
amisMake()->Table()->columnsTogglable(false)->itemActions([ amisMake()->Table()->columnsTogglable(false)->itemActions([
$this->succesAction()->reload('overtime-detail'), $this->succesAction()->reload('overtime-detail'),
@ -139,9 +133,4 @@ class OvertimeController extends AdminController
] ]
])->body([$detail, amisMake()->Divider(), $table]); ])->body([$detail, amisMake()->Divider(), $table]);
} }
public function getMorphAlias()
{
return (new OvertimeApply)->getMorphClass();
}
} }

View File

@ -22,6 +22,7 @@ class SignController extends AdminController
->tableLayout('fixed') ->tableLayout('fixed')
->headerToolbar([ ->headerToolbar([
...$this->baseHeaderToolBar(), ...$this->baseHeaderToolBar(),
$this->exportAction(),
]) ])
->bulkActions([]) ->bulkActions([])
->filter($this->baseFilter()->body([ ->filter($this->baseFilter()->body([
@ -38,7 +39,7 @@ class SignController extends AdminController
->columns([ ->columns([
amisMake()->TableColumn()->name('date')->label(__('employee_sign.date')), amisMake()->TableColumn()->name('date')->label(__('employee_sign.date')),
amisMake()->TableColumn()->name('store.title')->label(__('employee_sign.store_id')), amisMake()->TableColumn()->name('store.title')->label(__('employee_sign.store_id')),
amisMake()->TableColumn()->name('employee.name')->label(__('employee.name')), amisMake()->TableColumn()->name('employee.name')->label(__('employee_sign.employee_id')),
amisMake()->TableColumn()->name('sign_type')->label(__('employee_sign.sign_type')) amisMake()->TableColumn()->name('sign_type')->label(__('employee_sign.sign_type'))
->set('type', 'status') ->set('type', 'status')
->source(SignType::source()), ->source(SignType::source()),
@ -93,4 +94,20 @@ class SignController extends AdminController
] ]
])->body([$detail, amisMake()->Divider()->title(__('employee_sign.log')), $logs]); ])->body([$detail, amisMake()->Divider()->title(__('employee_sign.log')), $logs]);
} }
protected function exportMap($row)
{
$type = SignType::options();
$status = SignStatus::options();
return [
__('employee_sign.date') => data_get($row, 'date'),
__('employee_sign.store_id') => data_get($row, 'store.title'),
__('employee_sign.employee_id') => data_get($row, 'employee.name'),
__('employee_sign.sign_type') => data_get($type, data_get($row, 'sign_type')),
__('employee_sign.first_time') => data_get($row, 'first_time'),
__('employee_sign.last_time') => data_get($row, 'last_time'),
__('employee_sign.sign_status') => data_get($status, data_get($row, 'sign_status')),
__('employee_sign.remarks') => data_get($row, 'remarks'),
];
}
} }

View File

@ -22,7 +22,6 @@ class SignRepairController extends AdminController
public function list(): Page public function list(): Page
{ {
$subjectType = (new EmployeeSignRepair)->getMorphClass();
$crud = $this->baseCRUD() $crud = $this->baseCRUD()
->tableLayout('fixed') ->tableLayout('fixed')
->headerToolbar([ ->headerToolbar([
@ -46,12 +45,10 @@ class SignRepairController extends AdminController
amisMake()->DateRangeControl()->name('date_range')->label(__('employee_sign_repair.date')) amisMake()->DateRangeControl()->name('date_range')->label(__('employee_sign_repair.date'))
->columnRatio(3) ->columnRatio(3)
->clearable(), ->clearable(),
]), amisMake()->SelectControl()->name('check_status')->label(__('employee_sign_repair.check_status'))
amis()->GroupControl()->mode('horizontal')->body([ ->options(CheckStatus::options())
amisMake()->SelectControl()->name('check_status')->label(__('employee_sign_repair.check_status')) ->columnRatio(3)
->options(CheckStatus::options()) ->clearable()
->columnRatio(3)
->clearable()
]), ]),
])) ]))
->columns([ ->columns([
@ -62,17 +59,17 @@ class SignRepairController extends AdminController
amisMake()->Column()->name('repair_type')->label(__('employee_sign_repair.repair_type')) amisMake()->Column()->name('repair_type')->label(__('employee_sign_repair.repair_type'))
->set('type', 'mapping') ->set('type', 'mapping')
->map(SignTime::options()), ->map(SignTime::options()),
amisMake()->Column()->name('check_status')->label(__('employee_sign_repair.check_status')) amisMake()->Column()->name('workflow.check_status')->label(__('employee_sign_repair.check_status'))
->set('type', 'mapping') ->set('type', 'mapping')
->map(CheckStatus::options()), ->map(CheckStatus::options()),
$this->rowActions([ $this->rowActions([
$this->rowShowButton()->visible(Admin::user()->can('admin.hr.repairs.view')), $this->rowShowButton()->visible(Admin::user()->can('admin.hr.repairs.view')),
$this->rowEditTypeButton('drawer', 'xl') $this->rowEditTypeButton('drawer', 'xl')
->visible(Admin::user()->can('admin.hr.repairs.update')) ->visible(Admin::user()->can('admin.hr.repairs.update'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->rowDeleteButton() $this->rowDeleteButton()
->visible(Admin::user()->can('admin.hr.repairs.delete')) ->visible(Admin::user()->can('admin.hr.repairs.delete'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'), ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'),
$this->applyAction(), $this->applyAction(),
$this->cancelAction(), $this->cancelAction(),
]) ])
@ -105,7 +102,6 @@ class SignRepairController extends AdminController
public function detail(): Form public function detail(): Form
{ {
$subjectType = (new EmployeeSignRepair)->getMorphClass();
$detail = amisMake()->Property()->items([ $detail = amisMake()->Property()->items([
['label' => __('employee_sign_repair.store_id'), 'content' => '${store.title}'], ['label' => __('employee_sign_repair.store_id'), 'content' => '${store.title}'],
['label' => __('employee_sign_repair.employee_id'), 'content' => '${employee.name}'], ['label' => __('employee_sign_repair.employee_id'), 'content' => '${employee.name}'],
@ -113,19 +109,14 @@ class SignRepairController extends AdminController
['label' => __('employee_sign_repair.repair_type'), 'content' => amisMake()->Mapping()->name('repair_type')->map(SignTime::options())], ['label' => __('employee_sign_repair.repair_type'), 'content' => amisMake()->Mapping()->name('repair_type')->map(SignTime::options())],
['label' => __('employee_sign_repair.reason'), 'content' => '${reason}'], ['label' => __('employee_sign_repair.reason'), 'content' => '${reason}'],
['label' => __('employee_sign_repair.created_at'), 'content' => '${created_at}'], ['label' => __('employee_sign_repair.created_at'), 'content' => '${created_at}'],
['label' => __('employee_sign_repair.check_status'), 'content' => amisMake()->Mapping()->name('check_status')->map(CheckStatus::options())], ['label' => __('workflow_log.check_status'), 'content' => amisMake()->Mapping()->name('workflow.check_status')->map(CheckStatus::options())],
['label' => __('employee_sign_repair.checked_at'), 'content' => '${checked_at}'], ['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
['label' => __('employee_sign_repair.check_remarks'), 'content' => '${check_remarks}'], ['label' => __('workflow_log.check_remarks'), 'content' => '${workflow.check_remarks}'],
]); ]);
$table = amisMake()->Service() $table = amisMake()->Service()
->id('sign-repair-checklog-table') ->id('sign-repair-checklog-table')
->initFetch(false) ->initFetch(false)
->api( ->api(admin_url('api/workflow/logs') . '?id=${workflow.id}')
amisMake()->BaseApi()->method('get')->url(admin_url('api/workflow/logs'))->data([
'subject_type' => $subjectType,
'subject_id' => '${id}',
])
)
->body( ->body(
amisMake()->Table()->columnsTogglable(false)->itemActions([ amisMake()->Table()->columnsTogglable(false)->itemActions([
$this->succesAction()->reload('sign-repair-detail'), $this->succesAction()->reload('sign-repair-detail'),
@ -147,9 +138,4 @@ class SignRepairController extends AdminController
] ]
])->body([$detail, amisMake()->Divider(), $table]); ])->body([$detail, amisMake()->Divider(), $table]);
} }
public function getMorphAlias()
{
return (new EmployeeSignRepair)->getMorphClass();
}
} }

View File

@ -5,7 +5,7 @@ namespace App\Admin\Controllers\System;
use App\Admin\Controllers\AdminController; use App\Admin\Controllers\AdminController;
use App\Admin\Services\WorkFlowService; use App\Admin\Services\WorkFlowService;
use App\Enums\CheckType; use App\Enums\CheckType;
use App\Models\{Employee, WorkflowLog}; use App\Models\{Employee, WorkflowLog, WorkflowCheck};
use App\Models\Keyword; use App\Models\Keyword;
use Slowlyo\OwlAdmin\Renderers\Form; use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page; use Slowlyo\OwlAdmin\Renderers\Page;
@ -92,16 +92,8 @@ class WorkflowController extends AdminController
public function apply(Request $request) public function apply(Request $request)
{ {
$type = $request->input('subject_type'); $model = WorkflowCheck::findOrFail($request->input('id'));
$id = $request->input('subject_id'); $user = Employee::findOrFail($request->input('user'));
$subject = Relation::getMorphedModel($type);
$model = (new $subject)->findOrFail($id);
$user = $request->input('user');
if ($request->filled('user')) {
$user = Employee::findOrFail($request->input('user'));
} else {
$user = $model->employee;
}
try { try {
DB::beginTransaction(); DB::beginTransaction();
@ -118,10 +110,7 @@ class WorkflowController extends AdminController
public function cancel(Request $request) public function cancel(Request $request)
{ {
$type = $request->input('subject_type'); $model = WorkflowCheck::findOrFail($request->input('id'));
$id = $request->input('subject_id');
$subject = Relation::getMorphedModel($type);
$model = (new $subject)->findOrFail($id);
try { try {
DB::beginTransaction(); DB::beginTransaction();
@ -183,9 +172,7 @@ class WorkflowController extends AdminController
public function logs(Request $request) public function logs(Request $request)
{ {
$type = $request->input('subject_type'); $list = WorkflowLog::with(['checkUser'])->where('check_id', $request->input('id'))->sort()->get();
$id = $request->input('subject_id');
$list = WorkflowLog::with(['checkUser'])->where('subject_type', $type)->where('subject_id', $id)->sort()->get();
return $this->response()->success($list); return $this->response()->success($list);
} }

View File

@ -9,6 +9,19 @@ class EmployeeSignRepairFilter extends ModelFilter
{ {
protected $drop_id = false; protected $drop_id = false;
public $relations = [
'workflow' => [
'check_status' => 'check_status',
],
'store' => [
'store_title' => 'title',
],
'employee' => [
'employee_name' => 'name',
'employee_search' => 'search',
],
];
public function employeeId($key) public function employeeId($key)
{ {
$this->where('employee_id', $key); $this->where('employee_id', $key);
@ -32,9 +45,4 @@ class EmployeeSignRepairFilter extends ModelFilter
$end = Carbon::createFromTimestamp(data_get($dates, 1, time()))->endOfDay(); $end = Carbon::createFromTimestamp(data_get($dates, 1, time()))->endOfDay();
$this->whereBetween('date', [$start, $end]); $this->whereBetween('date', [$start, $end]);
} }
public function checkStatus($key)
{
$this->where('check_status', $key);
}
} }

View File

@ -10,6 +10,9 @@ class HolidayApplyFilter extends ModelFilter
protected $drop_id = false; protected $drop_id = false;
public $relations = [ public $relations = [
'workflow' => [
'check_status' => 'check_status',
],
'store' => [ 'store' => [
'store_title' => 'title', 'store_title' => 'title',
], ],
@ -28,9 +31,4 @@ class HolidayApplyFilter extends ModelFilter
{ {
$this->where('type_id', $key); $this->where('type_id', $key);
} }
public function checkStatus($key)
{
$this->where('check_status', $key);
}
} }

View File

@ -10,6 +10,9 @@ class OfficalBusinessFilter extends ModelFilter
protected $drop_id = false; protected $drop_id = false;
public $relations = [ public $relations = [
'workflow' => [
'check_status' => 'check_status',
],
'store' => [ 'store' => [
'store_title' => 'title', 'store_title' => 'title',
], ],

View File

@ -0,0 +1,21 @@
<?php
namespace App\Admin\Filters;
use EloquentFilter\ModelFilter;
use Carbon\Carbon;
class WorkflowCheckFilter extends ModelFilter
{
protected $drop_id = false;
public function employeeId($key)
{
$this->where('employee_id', $key);
}
public function checkStatus($key)
{
$this->where('check_status', $key);
}
}

View File

@ -3,7 +3,7 @@
namespace App\Admin\Services; namespace App\Admin\Services;
use App\Admin\Filters\EmployeeSignRepairFilter; use App\Admin\Filters\EmployeeSignRepairFilter;
use App\Models\{EmployeeSignRepair, WorkflowLog}; use App\Models\{EmployeeSignRepair, WorkflowCheck};
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
@ -12,7 +12,7 @@ use App\Enums\CheckStatus;
class EmployeeSignRepairService extends BaseService class EmployeeSignRepairService extends BaseService
{ {
protected array $withRelationships = ['employee', 'store']; protected array $withRelationships = ['employee', 'store', 'workflow'];
protected string $modelName = EmployeeSignRepair::class; protected string $modelName = EmployeeSignRepair::class;
@ -46,16 +46,17 @@ class EmployeeSignRepairService extends BaseService
public function preDelete(array $ids) public function preDelete(array $ids)
{ {
// 删除审核流程记录 // 删除审核流程记录
WorkflowLog::where('subject_type', (new WorkflowLog)->getMorphClass())->whereIn('subject_id', $ids)->delete(); WorkflowCheck::where('subject_type', (new WorkflowLog)->getMorphClass())->whereIn('subject_id', $ids)->delete();
return true; return true;
} }
public function validate($data, $model = null) public function validate($data, $model = null)
{ {
// 验证申请时间是否重叠
// todo
$unique = Rule::unique('employee_sign_repairs', 'date') $unique = Rule::unique('employee_sign_repairs', 'date')
->where('employee_id', data_get($data, 'employee_id', $model?->employee_id)) ->where('employee_id', data_get($data, 'employee_id', $model?->employee_id))
->where('repair_type', data_get($data, 'repair_type', $model?->repair_type)) ->where('repair_type', data_get($data, 'repair_type', $model?->repair_type));
->whereIn('check_status', [CheckStatus::Success, CheckStatus::Processing, CheckStatus::None]);
$createRules = [ $createRules = [
'employee_id' => ['required'], 'employee_id' => ['required'],
'repair_type' => ['required'], 'repair_type' => ['required'],

View File

@ -11,7 +11,7 @@ use Carbon\Carbon;
class HolidayApplyService extends BaseService class HolidayApplyService extends BaseService
{ {
protected array $withRelationships = ['store', 'employee', 'type']; protected array $withRelationships = ['store', 'employee', 'type', 'workflow'];
protected string $modelName = HolidayApply::class; protected string $modelName = HolidayApply::class;
@ -35,9 +35,7 @@ class HolidayApplyService extends BaseService
public function validate($data, $model = null) public function validate($data, $model = null)
{ {
// 验证申请时间是否重叠 // 验证申请时间是否重叠
if (HolidayApply::where('employee_id', data_get($data, 'employee_id', $model?->employee_id))->where(fn($q) => $q->whereBetween('start_at', [$data['start_at'], $data['end_at']])->orWhereBetween('end_at', [$data['start_at'], $data['end_at']]))->exists()) { // todo
return '该时间段已经申请过了';
}
$createRules = [ $createRules = [
'employee_id' => ['required'], 'employee_id' => ['required'],
'type_id' => ['required'], 'type_id' => ['required'],

View File

@ -11,7 +11,7 @@ use Carbon\Carbon;
class OfficalBusinessService extends BaseService class OfficalBusinessService extends BaseService
{ {
protected array $withRelationships = ['store', 'employee']; protected array $withRelationships = ['store', 'employee', 'workflow'];
protected string $modelName = OfficalBusiness::class; protected string $modelName = OfficalBusiness::class;
@ -36,9 +36,7 @@ class OfficalBusinessService extends BaseService
public function validate($data, $model = null) public function validate($data, $model = null)
{ {
// 验证申请时间是否重叠 // 验证申请时间是否重叠
if (OfficalBusiness::where('employee_id', data_get($data, 'employee_id', $model?->employee_id))->where(fn($q) => $q->whereBetween('start_at', [$data['start_at'], $data['end_at']])->orWhereBetween('end_at', [$data['start_at'], $data['end_at']]))->exists()) { // todo
return '该时间段已经申请过了';
}
$createRules = [ $createRules = [
'employee_id' => ['required'], 'employee_id' => ['required'],
'start_at' => ['required'], 'start_at' => ['required'],

View File

@ -11,7 +11,7 @@ use Carbon\Carbon;
class OvertimeApplyService extends BaseService class OvertimeApplyService extends BaseService
{ {
protected array $withRelationships = ['store', 'employee']; protected array $withRelationships = ['store', 'employee', 'workflow'];
protected string $modelName = OvertimeApply::class; protected string $modelName = OvertimeApply::class;
@ -38,9 +38,7 @@ class OvertimeApplyService extends BaseService
public function validate($data, $model = null) public function validate($data, $model = null)
{ {
// 验证申请时间是否重叠 // 验证申请时间是否重叠
if (OvertimeApply::where('employee_id', data_get($data, 'employee_id', $model?->employee_id))->where(fn($q) => $q->whereBetween('start_at', [$data['start_at'], $data['end_at']])->orWhereBetween('end_at', [$data['start_at'], $data['end_at']]))->exists()) { // todo
return '该时间段已经申请过了';
}
$createRules = [ $createRules = [
'employee_id' => ['required'], 'employee_id' => ['required'],
'start_at' => ['required'], 'start_at' => ['required'],

View File

@ -3,7 +3,7 @@
namespace App\Admin\Services; namespace App\Admin\Services;
use App\Enums\{CheckType, CheckStatus}; use App\Enums\{CheckType, CheckStatus};
use App\Models\{Employee, Store, Keyword, Workflow, WorkflowLog}; use App\Models\{Employee, Store, Keyword, Workflow, WorkflowCheck, WorkflowLog};
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule; use Illuminate\Validation\Rule;
use App\Contracts\Checkable; use App\Contracts\Checkable;
@ -21,30 +21,34 @@ class WorkFlowService extends BaseService
* 1. 待审核 Model 实现 Checkable * 1. 待审核 Model 实现 Checkable
* 2. 生成全部的审核流程 * 2. 生成全部的审核流程
* *
* @param Checkable $subject 待审核记录 * @param WorkflowCheck $check 待审核记录
* @param Employee $user 申请人 * @param Employee $user 申请人
* *
* @return boolean true: 成功, false: 失败, $this->getError(): 错误消息 * @return boolean true: 成功, false: 失败, $this->getError(): 错误消息
*/ */
public function apply(Checkable $subject, Employee $user) public function apply(WorkflowCheck $check, Employee $user)
{ {
if ($subject->check_status === CheckStatus::Success->value) { if ($check->check_status === CheckStatus::Success->value) {
return $this->setError('已经审核通过'); return $this->setError('已经审核通过');
} }
if ($subject->check_status === CheckStatus::Processing->value) { if ($check->check_status === CheckStatus::Processing->value) {
return $this->setError('正在审核中'); return $this->setError('正在审核中');
} }
$workflow = Workflow::where('key', $subject->getCheckKey())->first(); $workflow = Workflow::where('key', $check->key)->first();
// 没有配置审核流程, 直接通过 // 没有配置审核流程, 直接通过
if (!$workflow || !$workflow->config) { if (!$workflow || !$workflow->config) {
$subject->checkSuccess(); $this->success();
return true; return true;
} }
$jobs = Keyword::where('parent_key', 'job')->get(); $jobs = Keyword::where('parent_key', 'job')->get();
$config = collect($workflow->config)->sortBy('sort'); $config = collect($workflow->config)->sortBy('sort');
$batchId = WorkflowLog::where('subject_type', $subject->getMorphClass())->where('subject_id', $subject->id)->max('batch_id') + 1; $batchId = $check->logs()->max('batch_id') + 1;
$subjectData = $subject->toArray(); $check->update([
'subject_data' => $check->subject->toArray(),
'check_status' => CheckStatus::Processing,
'employee_id' => $user->id,
]);
foreach($config as $item) { foreach($config as $item) {
$checkValue = ''; $checkValue = '';
$checkName = ''; $checkName = '';
@ -69,19 +73,36 @@ class WorkFlowService extends BaseService
return $this->setError('未知的审核类型: ' . $item['type']); return $this->setError('未知的审核类型: ' . $item['type']);
break; break;
} }
$subject->workflows()->create([ $check->logs()->create([
'batch_id' => $batchId, 'batch_id' => $batchId,
'check_type' => $item['type'], 'check_type' => $item['type'],
'check_value' => $checkValue, 'check_value' => $checkValue,
'check_name' => $checkName, 'check_name' => $checkName,
'user_id' => $user->id,
'subject_data' => $subjectData,
'sort' => $item['sort'] 'sort' => $item['sort']
]); ]);
} }
$subject->checkApply();
// 开启第一个审核流程 // 开启第一个审核流程
$this->next($subject); $this->next($check);
return true;
}
public function success(WorkflowCheck $check, array $options = [])
{
$check->update([
'check_status' => CheckStatus::Success,
'checked_at' => data_get($options, 'checked_at', now()),
'check_remarks' => data_get($options, 'remarks')
]);
return true;
}
public function fail(WorkflowCheck $check, array $options = [])
{
$check->update([
'check_status' => CheckStatus::Fail,
'check_remarks' => data_get($options, 'remarks'),
'checked_at' => data_get($options, 'checked_at', now()),
]);
return true; return true;
} }
@ -91,10 +112,13 @@ class WorkFlowService extends BaseService
* 2. 更新申请记录的状态 * 2. 更新申请记录的状态
* *
*/ */
public function cancel(Checkable $subject) public function cancel(WorkflowCheck $check)
{ {
$subject->workflows()->whereIn('check_status', [CheckStatus::None, CheckStatus::Processing])->delete(); $check->logs()->whereIn('check_status', [CheckStatus::None, CheckStatus::Processing])->delete();
$subject->checkCancel(); $check->update([
'check_status' => CheckStatus::Cancel,
]);
return true; return true;
} }
@ -121,42 +145,39 @@ class WorkFlowService extends BaseService
$attributes['check_user_id'] = $user->id; $attributes['check_user_id'] = $user->id;
$log->update($attributes); $log->update($attributes);
$subject = $log->subject; $check = $log->check;
// 审核未通过, 删除剩下的流程 if ($status) {
if (!$status) { return $this->next($check);
WorkflowLog::where('subject_type', $log->subject_type)->where('subject_id', $log->subject_id)->where('check_status', CheckStatus::None)->delete(); } else {
$subject->checkFail($options); return $this->fail($check, $options);
return true;
} }
return $this->next($subject);
} }
/** /**
* 开启下一个审核流程 * 开启下一个审核流程
* *
* @param Checkable $subject * @param WorkflowCheck $check
* @return boolean * @return boolean
*/ */
public function next(Checkable $subject) public function next(WorkflowCheck $check)
{ {
$log = $subject->workflows()->where('check_status', CheckStatus::None)->orderBy('sort')->first(); $log = $check->logs()->where('check_status', CheckStatus::None)->orderBy('sort')->first();
if ($log) { if ($log) {
$log->update(['check_status' => CheckStatus::Processing]); $log->update(['check_status' => CheckStatus::Processing]);
// 申请人自动审核通过 // 申请人自动审核通过
if ($this->authCheck($subject->employee, $log)) { if ($this->authCheck($check->employee, $log)) {
return $this->check($subject->employee, $log, true, ['remarks' => '自动审核通过']); return $this->check($check->employee, $log, true, ['remarks' => '自动审核通过']);
} }
} else { } else {
// 没有审核流程了 // 没有审核流程了, 审核完成
$subject->checkSuccess(); return $this->success($check);
} }
return true; return true;
} }
/** /**
* 员工是否有权限审核 * 是否有权限审核
*/ */
public function authCheck(Employee $user, WorkflowLog $log) public function authCheck(Employee $user, WorkflowLog $log)
{ {

View File

@ -14,5 +14,5 @@ interface Checkable
public function getCheckKey(); public function getCheckKey();
public function workflows(); public function workflow();
} }

View File

@ -29,7 +29,7 @@ class EmployeeSignLog extends Model
public function modelFilter() public function modelFilter()
{ {
return \App\Admin\Filters\EmployeeSignRepairFilter::class; return \App\Admin\Filters\EmployeeSignLogFilter::class;
} }
public function store() public function store()

View File

@ -3,33 +3,31 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Enums\{SignTime, CheckStatus}; use App\Enums\{SignTime};
use App\Traits\HasDateTimeFormatter; use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
use App\Contracts\Checkable;
use App\Traits\HasCheckable; use App\Traits\HasCheckable;
/** /**
* 补卡申请 * 补卡申请
*/ */
class EmployeeSignRepair extends Model implements Checkable class EmployeeSignRepair extends Model
{ {
use HasDateTimeFormatter, Filterable, HasCheckable; use HasDateTimeFormatter, Filterable, HasCheckable;
protected $table = 'employee_sign_repairs'; protected $table = 'employee_sign_repairs';
protected $fillable = ['date', 'store_id', 'employee_id', 'reason', 'repair_type', 'check_status', 'checked_at', 'check_remarks']; protected $fillable = ['date', 'store_id', 'employee_id', 'reason', 'repair_type'];
protected $casts = [ protected $casts = [
'date' => 'date:Y-m-d', 'date' => 'date:Y-m-d',
'checked_at' => 'datetime', 'checked_at' => 'datetime',
'repair_type' => SignTime::class, 'repair_type' => SignTime::class,
'check_status' => CheckStatus::class,
]; ];
public function modelFilter() public function modelFilter()
{ {
return EmployeeSignLogFilter::class; return \App\Admin\Filters\EmployeeSignRepairFilter::class;
} }
public function store() public function store()

View File

@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Contracts\Checkable;
use App\Traits\HasCheckable; use App\Traits\HasCheckable;
use App\Traits\HasDateTimeFormatter; use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
@ -12,16 +11,15 @@ use App\Enums\{CheckStatus};
/** /**
* 请假申请 * 请假申请
*/ */
class HolidayApply extends Model implements Checkable class HolidayApply extends Model
{ {
use Filterable, HasCheckable, HasDateTimeFormatter; use Filterable, HasCheckable, HasDateTimeFormatter;
protected $fillable = ['store_id', 'employee_id', 'start_at', 'end_at', 'type_id', 'reason', 'check_status', 'checked_at', 'check_remarks']; protected $fillable = ['store_id', 'employee_id', 'start_at', 'end_at', 'type_id', 'reason'];
protected $casts = [ protected $casts = [
'start_at' => 'date:Y-m-d', 'start_at' => 'date:Y-m-d',
'end_at' => 'date:Y-m-d', 'end_at' => 'date:Y-m-d',
'check_status' => CheckStatus::class,
]; ];
public function modelFilter() public function modelFilter()
@ -34,6 +32,11 @@ class HolidayApply extends Model implements Checkable
return $this->belongsTo(Store::class, 'store_id'); return $this->belongsTo(Store::class, 'store_id');
} }
public function employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
public function type() public function type()
{ {
// holiday_type // holiday_type

View File

@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Contracts\Checkable;
use App\Traits\HasCheckable; use App\Traits\HasCheckable;
use App\Traits\HasDateTimeFormatter; use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
@ -12,23 +11,27 @@ use App\Enums\{CheckStatus};
/** /**
* 出差报备 * 出差报备
*/ */
class OfficalBusiness extends Model implements Checkable class OfficalBusiness extends Model
{ {
use HasCheckable, HasDateTimeFormatter, Filterable; use HasCheckable, HasDateTimeFormatter, Filterable;
protected $table = 'offical_business'; protected $table = 'offical_business';
protected $fillable = ['store_id', 'employee_id', 'start_at', 'end_at', 'address', 'reason', 'check_status', 'checked_at', 'check_remarks']; protected $fillable = ['store_id', 'employee_id', 'start_at', 'end_at', 'address', 'reason'];
protected $casts = [ protected $casts = [
'start_at' => 'date:Y-m-d', 'start_at' => 'date:Y-m-d',
'end_at' => 'date:Y-m-d', 'end_at' => 'date:Y-m-d',
'check_status' => CheckStatus::class,
]; ];
public function modelFilter() public function modelFilter()
{ {
return App\Admin\Filters\OfficalBusinessFilter::class; return \App\Admin\Filters\OfficalBusinessFilter::class;
}
public function employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
} }
public function store() public function store()

View File

@ -3,7 +3,6 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use App\Contracts\Checkable;
use App\Traits\HasCheckable; use App\Traits\HasCheckable;
use App\Traits\HasDateTimeFormatter; use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable; use EloquentFilter\Filterable;
@ -12,22 +11,26 @@ use App\Enums\{CheckStatus};
/** /**
* 加班申请 * 加班申请
*/ */
class OvertimeApply extends Model implements Checkable class OvertimeApply extends Model
{ {
use Filterable, HasDateTimeFormatter, HasCheckable; use Filterable, HasDateTimeFormatter, HasCheckable;
protected $fillable = ['store_id', 'employee_id', 'date', 'start_at', 'end_at', 'hours', 'reason', 'check_status', 'checked_at', 'check_remarks']; protected $fillable = ['store_id', 'employee_id', 'date', 'start_at', 'end_at', 'hours', 'reason'];
protected $casts = [ protected $casts = [
'date' => 'date:Y-m-d', 'date' => 'date:Y-m-d',
'start_at' => 'datetime', 'start_at' => 'datetime',
'end_at' => 'datetime', 'end_at' => 'datetime',
'check_status' => CheckStatus::class,
]; ];
public function modelFilter() public function modelFilter()
{ {
return App\Admin\Filters\HolidayApplyFilter::class; return \App\Admin\Filters\HolidayApplyFilter::class;
}
public function employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
} }
public function store() public function store()

View File

@ -0,0 +1,48 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\Employee;
use App\Enums\CheckStatus;
use App\Traits\HasDateTimeFormatter;
use EloquentFilter\Filterable;
/**
* 审核申请
*/
class WorkflowCheck extends Model
{
use HasDateTimeFormatter, Filterable;
protected $fillable = ['subject_type', 'subject_id', 'subject_data', 'key', 'employee_id', 'check_status', 'checked_at', 'check_remarks'];
protected $casts = [
'subject_data' => 'json',
'check_status' => CheckStatus::class,
'checked_at' => 'datetime',
];
public function modelFilter()
{
return \App\Admin\Filters\WorkflowCheckFilter::class;
}
public function employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
public function subject()
{
// 定义反向关联
// $this->morphMany(WorkflowLog::class, 'subject');
return $this->morphTo();
}
public function logs()
{
return $this->hasMany(WorkflowLog::class, 'check_id');
}
}

View File

@ -11,28 +11,25 @@ use Illuminate\Database\Eloquent\Model;
*/ */
class WorkflowLog extends Model class WorkflowLog extends Model
{ {
protected $fillable = ['batch_id', 'check_type', 'check_value', 'check_name', 'subject_type', 'subject_id', 'subject_data', 'check_user_id', 'checked_at', 'remarks', 'check_status', 'sort']; protected $fillable = ['check_id', 'batch_id', 'check_type', 'check_value', 'check_name', 'check_user_id', 'checked_at', 'remarks', 'check_status', 'sort'];
protected $casts = [ protected $casts = [
'check_type' => CheckType::class, 'check_type' => CheckType::class,
'check_status' => CheckStatus::class, 'check_status' => CheckStatus::class,
'subject_data' => 'json',
]; ];
public function check()
{
return $this->belongsTo(WorkflowCheck::class, 'check_id');
}
public function checkUser() public function checkUser()
{ {
return $this->belongsTo(Employee::class, 'check_user_id'); return $this->belongsTo(Employee::class, 'check_user_id');
} }
public function subject()
{
// 定义反向关联
// $this->morphMany(WorkflowLog::class, 'subject');
return $this->morphTo();
}
public function scopeSort($q) public function scopeSort($q)
{ {
return $q->orderBy('batch_id')->orderBy('sort'); return $q->orderBy('sort');
} }
} }

View File

@ -6,11 +6,6 @@ use App\Enums\{CheckStatus};
trait HasCheckActions trait HasCheckActions
{ {
public function getMorphAlias()
{
// return (new EmployeeSignRepair)->getMorphClass();
return '';
}
public function applyAction() public function applyAction()
{ {
return amisMake() return amisMake()
@ -18,11 +13,11 @@ trait HasCheckActions
->label('发起审核') ->label('发起审核')
->level('link') ->level('link')
->api(amisMake()->BaseApi()->url(admin_url('api/workflow/apply'))->method('post')->data([ ->api(amisMake()->BaseApi()->url(admin_url('api/workflow/apply'))->method('post')->data([
'subject_type' => $this->getMorphAlias(), 'id' => '${workflow.id}',
'subject_id' => '${id}' 'user' => '${employee_id}',
])) ]))
->confirmText(__('admin.confirm')) ->confirmText(__('admin.confirm'))
->visibleOn('${OR(check_status == '.CheckStatus::None->value.', check_status == '.CheckStatus::Cancel->value.', check_status == '.CheckStatus::Fail->value.')}'); ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}');
} }
@ -33,11 +28,10 @@ trait HasCheckActions
->label('取消审核') ->label('取消审核')
->level('link') ->level('link')
->api(amisMake()->BaseApi()->url(admin_url('api/workflow/cancel'))->method('post')->data([ ->api(amisMake()->BaseApi()->url(admin_url('api/workflow/cancel'))->method('post')->data([
'subject_type' => $this->getMorphAlias(), 'id' => '${workflow.id}'
'subject_id' => '${id}',
])) ]))
->confirmText(__('admin.confirm')) ->confirmText(__('admin.confirm'))
->visibleOn('${check_status == '.CheckStatus::Processing->value.'}'); ->visibleOn('${workflow.check_status == '.CheckStatus::Processing->value.'}');
} }
public function succesAction() public function succesAction()
@ -59,7 +53,7 @@ trait HasCheckActions
->level('link') ->level('link')
->dialog(amisMake()->Dialog()->title('审核不通过')->body( ->dialog(amisMake()->Dialog()->title('审核不通过')->body(
amisMake()->Form()->title('')->api('post:'.admin_url('api/workflow/fail'))->body([ amisMake()->Form()->title('')->api('post:'.admin_url('api/workflow/fail'))->body([
amisMake()->HiddenControl()->name('id'), amisMake()->HiddenControl()->name('id')->value('${id}'),
amisMake()->TextControl()->name('remarks')->label(__('workflow_log.remarks'))->required(), amisMake()->TextControl()->name('remarks')->label(__('workflow_log.remarks'))->required(),
]) ])
)) ))

View File

@ -3,83 +3,33 @@
namespace App\Traits; namespace App\Traits;
use App\Enums\CheckStatus; use App\Enums\CheckStatus;
use App\Models\{WorkflowLog, Employee}; use App\Models\{WorkflowCheck, Employee};
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Str; use Illuminate\Support\Str;
trait HasCheckable trait HasCheckable
{ {
public function checkApply() protected $check_key = '';
protected static function booted(): void
{ {
$this->update([ static::created(function ($model) {
'check_status' => CheckStatus::Processing, // 创建审核申请
'checked_at' => null, $model->workflow()->create([
'check_remarks' => '', 'key' => $model->getCheckKey(),
]); ]);
} });
/**
* 审核通过
*
* @param array $options {remarks: 不通过原因, time: 审核时间(默认当前时间)}
*/
public function checkSuccess(array $options = [])
{
$attributes = ['check_status' => CheckStatus::Success];
$attributes['checked_at'] = data_get($options, 'time', now());
$attributes['check_remarks'] = data_get($options, 'remarks');
$this->update($attributes);
}
/**
* 审核未通过
*
* @param array $options {remarks: 不通过原因, time: 审核时间(默认当前时间)}
*/
public function checkFail(array $options = [])
{
$attributes = ['check_status' => CheckStatus::Fail];
$attributes['checked_at'] = data_get($options, 'time', now());
$attributes['check_remarks'] = data_get($options, 'remarks');
$this->update($attributes);
}
public function checkCancel(array $options = [])
{
$this->update([
'check_status' => CheckStatus::Cancel,
'checked_at' => data_get($options, 'time', now()),
]);
} }
public function getCheckKey() public function getCheckKey()
{ {
return Str::snake(class_basename(__CLASS__)); return $this->check_key ?: Str::snake(class_basename(__CLASS__));
} }
/** /**
* 关联审核流水 * 关联审核流水
*/ */
public function workflows() public function workflow()
{ {
return $this->morphMany(WorkflowLog::class, 'subject'); return $this->morphOne(WorkflowCheck::class, 'subject');
}
/**
* 关联申请人
*/
public function employee()
{
return $this->belongsTo(Employee::class, 'employee_id');
}
/**
* 查询审核通过的记录
*
* @param Builder $q
*/
public function scopeChecked(Builder $q): Builder
{
return $q->where('check_status', CheckStatus::Success);
} }
} }

View File

@ -22,14 +22,27 @@ return new class extends Migration
$table->comment('审核流程'); $table->comment('审核流程');
}); });
Schema::create('workflow_checks', function (Blueprint $table) {
$table->id();
$table->string('key')->comment('审核流程的key');
$table->morphs('subject');
$table->json('subject_data')->nullable('审核内容');
$table->foreignId('employee_id')->nullable()->comment('申请人, employees.id');
$table->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->timestamps();
$table->comment('审核申请');
});
Schema::create('workflow_logs', function (Blueprint $table) { Schema::create('workflow_logs', function (Blueprint $table) {
$table->id(); $table->id();
$table->unsignedBigInteger('batch_id')->comment('批次号(为同一批审核流程设置一个ID)'); $table->unsignedInteger('batch_id')->default(1)->comment('批次号(每次申请, 批次号递增)');
$table->foreignId('check_id')->comment('审核申请, workflow_checks.id');
$table->string('check_type')->comment('审核类型{job, user}'); $table->string('check_type')->comment('审核类型{job, user}');
$table->string('check_value')->comment('审核类型值'); $table->string('check_value')->comment('审核类型值');
$table->string('check_name')->comment('审核名称(展示用)'); $table->string('check_name')->comment('审核名称(展示用)');
$table->nullableMorphs('subject');
$table->json('subject_data')->nullable('审核内容');
$table->unsignedBigInteger('check_user_id')->nullable()->comment('实际审核人(admin_users.id)'); $table->unsignedBigInteger('check_user_id')->nullable()->comment('实际审核人(admin_users.id)');
$table->timestamp('checked_at')->nullable()->comment('审核时间'); $table->timestamp('checked_at')->nullable()->comment('审核时间');
$table->string('remarks')->nullable()->comment('审核备注'); $table->string('remarks')->nullable()->comment('审核备注');

View File

@ -3,7 +3,7 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use App\Enums\CheckStatus;
return new class extends Migration return new class extends Migration
{ {
@ -55,11 +55,7 @@ return new class extends Migration
$table->foreignId('store_id')->comment('门店, stores.id'); $table->foreignId('store_id')->comment('门店, stores.id');
$table->foreignId('employee_id')->comment('员工, employees.id'); $table->foreignId('employee_id')->comment('员工, employees.id');
$table->string('reason')->comment('补卡原因'); $table->string('reason')->comment('补卡原因');
$table->unsignedInteger('repair_type')->default(1)->comment('上班/下班 补卡'); $table->unsignedInteger('repair_type')->default(1)->comment('上班/下班');
$table->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->timestamps(); $table->timestamps();

View File

@ -3,7 +3,6 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use App\Enums\CheckStatus;
return new class extends Migration return new class extends Migration
{ {
@ -20,10 +19,6 @@ return new class extends Migration
$table->datetime('end_at')->comment('开始时间'); $table->datetime('end_at')->comment('开始时间');
$table->string('type_id')->comment('类型(holiday_type), keywords.key'); $table->string('type_id')->comment('类型(holiday_type), keywords.key');
$table->string('reason')->comment('事由'); $table->string('reason')->comment('事由');
$table->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->timestamps(); $table->timestamps();
$table->comment('请假申请'); $table->comment('请假申请');
}); });

View File

@ -3,7 +3,6 @@
use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use App\Enums\CheckStatus;
return new class extends Migration return new class extends Migration
{ {
@ -21,10 +20,6 @@ return new class extends Migration
$table->timestamp('end_at')->comment('开始时间'); $table->timestamp('end_at')->comment('开始时间');
$table->unsignedInteger('hours')->comment('时长'); $table->unsignedInteger('hours')->comment('时长');
$table->string('reason')->nullable()->comment('事由'); $table->string('reason')->nullable()->comment('事由');
$table->unsignedInteger('check_status')->default(CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->timestamps(); $table->timestamps();
}); });
} }

View File

@ -19,10 +19,6 @@ return new class extends Migration
$table->timestamp('end_at')->comment('开始时间'); $table->timestamp('end_at')->comment('开始时间');
$table->string('address')->comment('目的地'); $table->string('address')->comment('目的地');
$table->string('reason')->nullable()->comment('事由'); $table->string('reason')->nullable()->comment('事由');
$table->unsignedInteger('check_status')->default(App\Enums\CheckStatus::None->value)->comment('审核状态');
$table->timestamp('checked_at')->nullable()->comment('审核通过时间');
$table->string('check_remarks')->nullable()->comment('审核未通过原因');
$table->timestamps(); $table->timestamps();
$table->comment('出差报备'); $table->comment('出差报备');
}); });

View File

@ -16,15 +16,15 @@ class EmployeeSeeder extends Seeder
*/ */
public function run(): void public function run(): void
{ {
DB::table('employee_jobs')->truncate(); // DB::table('employee_jobs')->truncate();
Employee::where('admin_user_id', '!=', 1)->delete(); // Employee::where('admin_user_id', '!=', 1)->delete();
(new EmployeeFactory)->count(100)->create(); // (new EmployeeFactory)->count(100)->create();
Store::truncate(); // Store::truncate();
Store::factory()->count(10)->create(); // Store::factory()->count(10)->create();
// EmployeeSign::truncate(); EmployeeSign::truncate();
// EmployeeSignLog::truncate(); EmployeeSignLog::truncate();
// EmployeeSignLog::factory()->count(100)->create(); EmployeeSignLog::factory()->count(100)->create();
} }
} }