init code
This commit is contained in:
parent
2735b14c03
commit
eeef8ea68c
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.DS_Store
|
||||||
|
phpunit.phar
|
||||||
|
/vendor
|
||||||
|
composer.phar
|
||||||
|
composer.lock
|
||||||
|
*.project
|
||||||
|
.idea/
|
||||||
20
LICENSE
Normal file
20
LICENSE
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Jens Segers
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
47
README.md
47
README.md
@ -1,2 +1,47 @@
|
|||||||
# laravel-admin-ext-scheduling
|
Scheduling task manager for laravel-admin
|
||||||
|
============================
|
||||||
|
|
||||||
|
[](https://styleci.io/repos/99676857)
|
||||||
|
[](https://packagist.org/packages/laravel-admin-ext/scheduling)
|
||||||
|
[](https://packagist.org/packages/laravel-admin-ext/scheduling)
|
||||||
|
[]()
|
||||||
|
|
||||||
|
A web interface for manage task scheduling in laravel.
|
||||||
|
|
||||||
|
[Documentation](http://laravel-admin.org/docs/#/en/extension-scheduling) | [中文文档](http://laravel-admin.org/docs/#/zh/extension-scheduling)
|
||||||
|
|
||||||
|
## Screenshot
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```
|
||||||
|
$ composer require laravel-admin-ext/scheduling
|
||||||
|
|
||||||
|
|
||||||
|
$ php artisan admin:import scheduling
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://your-host/admin/scheduling`.
|
||||||
|
|
||||||
|
Try to add a scheduling task in `app/Console/Kernel.php` like this:
|
||||||
|
|
||||||
|
```php
|
||||||
|
class Kernel extends ConsoleKernel
|
||||||
|
{
|
||||||
|
protected function schedule(Schedule $schedule)
|
||||||
|
{
|
||||||
|
$schedule->command('inspire')->everyTenMinutes();
|
||||||
|
|
||||||
|
$schedule->command('route:list')->dailyAt('02:00');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
And you can find these tasks in scheduling panel.
|
||||||
|
|
||||||
|
License
|
||||||
|
------------
|
||||||
|
Licensed under [The MIT License (MIT)](LICENSE).
|
||||||
|
|||||||
36
composer.json
Normal file
36
composer.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "aix/laravel-admin-ext-scheduling",
|
||||||
|
"description": "Task scheduling extension for laravel-admin",
|
||||||
|
"type": "library",
|
||||||
|
"keywords": ["laravel-admin", "task", "Scheduling"],
|
||||||
|
"homepage": "https://github.com/laravel-admin-extensions/scheduling",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "z-song",
|
||||||
|
"email": "zosong@126.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.0.0",
|
||||||
|
"laravel/framework": "~5.5",
|
||||||
|
"aix/laravel-admin": "1.0.*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "~6.0",
|
||||||
|
"laravel/laravel": "~5.5"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Encore\\Admin\\Scheduling\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Encore\\Admin\\Scheduling\\SchedulingServiceProvider"
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
resources/views/index.blade.php
Normal file
73
resources/views/index.blade.php
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<script data-exec-on-popstate>
|
||||||
|
$(function () {
|
||||||
|
$('.run-task').click(function (e) {
|
||||||
|
var id = $(this).data('id');
|
||||||
|
NProgress.start();
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
url: '{{ route('scheduling-run') }}',
|
||||||
|
data: {id: id, _token: LA.token},
|
||||||
|
success: function (data) {
|
||||||
|
if (typeof data === 'object') {
|
||||||
|
$('.output-box').removeClass('hide');
|
||||||
|
$('.output-box .output-body').html(data.data);
|
||||||
|
}
|
||||||
|
NProgress.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.output-body {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background: #000000;
|
||||||
|
color: #00fa4a;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<div class="box-body no-padding">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 10px">#</th>
|
||||||
|
<th>Task</th>
|
||||||
|
<th>Run at</th>
|
||||||
|
<th>Next run time</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Run</th>
|
||||||
|
</tr>
|
||||||
|
@foreach($events as $index => $event)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $index+1 }}.</td>
|
||||||
|
<td><code>{{ $event['task']['name'] }}</code></td>
|
||||||
|
<td><span class="label label-success">{{ $event['expression'] }}</span> {{ $event['readable'] }}</td>
|
||||||
|
<td>{{ $event['nextRunDate'] }}</td>
|
||||||
|
<td>{{ $event['description'] }}</td>
|
||||||
|
<td><a class="btn btn-xs btn-primary run-task" data-id="{{ $index+1 }}">Run</a></td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box box-default output-box hide">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<i class="fa fa-terminal"></i>
|
||||||
|
|
||||||
|
<h3 class="box-title">Output</h3>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<div class="box-body">
|
||||||
|
<pre class="output-body"></pre>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
</div>
|
||||||
1400
src/CronSchedule.php
Normal file
1400
src/CronSchedule.php
Normal file
File diff suppressed because it is too large
Load Diff
162
src/Scheduling.php
Normal file
162
src/Scheduling.php
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Encore\Admin\Scheduling;
|
||||||
|
|
||||||
|
use Encore\Admin\Admin;
|
||||||
|
use Encore\Admin\Extension;
|
||||||
|
use Illuminate\Console\Scheduling\CallbackEvent;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class Scheduling extends Extension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string out put file for command.
|
||||||
|
*/
|
||||||
|
protected $sendOutputTo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all events in console kernel.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getKernelEvents()
|
||||||
|
{
|
||||||
|
app()->make('Illuminate\Contracts\Console\Kernel');
|
||||||
|
|
||||||
|
return app()->make('Illuminate\Console\Scheduling\Schedule')->events();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all formatted tasks.
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getTasks()
|
||||||
|
{
|
||||||
|
$tasks = [];
|
||||||
|
|
||||||
|
foreach ($this->getKernelEvents() as $event) {
|
||||||
|
$tasks[] = [
|
||||||
|
'task' => $this->formatTask($event),
|
||||||
|
'expression' => $event->expression,
|
||||||
|
'nextRunDate' => $event->nextRunDate()->format('Y-m-d H:i:s'),
|
||||||
|
'description' => $event->description,
|
||||||
|
'readable' => CronSchedule::fromCronString($event->expression)->asNaturalLanguage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a giving task.
|
||||||
|
*
|
||||||
|
* @param $event
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function formatTask($event)
|
||||||
|
{
|
||||||
|
if ($event instanceof CallbackEvent) {
|
||||||
|
return [
|
||||||
|
'type' => 'closure',
|
||||||
|
'name' => 'Closure',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Str::contains($event->command, '\'artisan\'')) {
|
||||||
|
$exploded = explode(' ', $event->command);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => 'artisan',
|
||||||
|
'name' => 'artisan '.implode(' ', array_slice($exploded, 2)),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'type' => 'command',
|
||||||
|
'name' => $event->command,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run specific task.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function runTask($id)
|
||||||
|
{
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
/** @var \Illuminate\Console\Scheduling\Event $event */
|
||||||
|
$event = $this->getKernelEvents()[$id - 1];
|
||||||
|
|
||||||
|
$event->sendOutputTo($this->getOutputTo());
|
||||||
|
|
||||||
|
$event->run(app());
|
||||||
|
|
||||||
|
return $this->readOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getOutputTo()
|
||||||
|
{
|
||||||
|
if (!$this->sendOutputTo) {
|
||||||
|
$this->sendOutputTo = storage_path('app/task-schedule.output');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sendOutputTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read output info from output file.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function readOutput()
|
||||||
|
{
|
||||||
|
return file_get_contents($this->getOutputTo());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap this package.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function boot()
|
||||||
|
{
|
||||||
|
static::registerRoutes();
|
||||||
|
|
||||||
|
Admin::extend('scheduling', __CLASS__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register routes for laravel-admin.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected static function registerRoutes()
|
||||||
|
{
|
||||||
|
parent::routes(function ($router) {
|
||||||
|
/* @var \Illuminate\Routing\Router $router */
|
||||||
|
$router->get('scheduling', 'Encore\Admin\Scheduling\SchedulingController@index')->name('scheduling-index');
|
||||||
|
$router->post('scheduling/run', 'Encore\Admin\Scheduling\SchedulingController@runEvent')->name('scheduling-run');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function import()
|
||||||
|
{
|
||||||
|
parent::createMenu('Scheduling', 'scheduling', 'fa-clock-o');
|
||||||
|
|
||||||
|
parent::createPermission('Scheduling', 'ext.scheduling', 'scheduling*');
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/SchedulingController.php
Normal file
54
src/SchedulingController.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Encore\Admin\Scheduling;
|
||||||
|
|
||||||
|
use Encore\Admin\Facades\Admin;
|
||||||
|
use Encore\Admin\Layout\Content;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class SchedulingController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Index interface.
|
||||||
|
*
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return Admin::content(function (Content $content) {
|
||||||
|
$content->header('任务列表');
|
||||||
|
|
||||||
|
$scheduling = new Scheduling();
|
||||||
|
|
||||||
|
$content->body(view('laravel-admin-scheduling::index', [
|
||||||
|
'events' => $scheduling->getTasks(),
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Request $request
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function runEvent(Request $request)
|
||||||
|
{
|
||||||
|
$scheduling = new Scheduling();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$output = $scheduling->runTask($request->get('id'));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'status' => true,
|
||||||
|
'message' => 'success',
|
||||||
|
'data' => $output,
|
||||||
|
];
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return [
|
||||||
|
'status' => false,
|
||||||
|
'message' => 'failed',
|
||||||
|
'data' => $e->getMessage(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/SchedulingServiceProvider.php
Normal file
18
src/SchedulingServiceProvider.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Encore\Admin\Scheduling;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class SchedulingServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
$this->loadViewsFrom(__DIR__.'/../resources/views', 'laravel-admin-scheduling');
|
||||||
|
|
||||||
|
Scheduling::boot();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user