first
This commit is contained in:
4
modules/Linker/.gitignore
vendored
Normal file
4
modules/Linker/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.idea
|
||||
vendor
|
||||
.DS_Store
|
||||
composer.lock
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLinkerRelationsTable extends Migration
|
||||
{
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('linker_relations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('linker_id')->index();
|
||||
$table->morphs('model');
|
||||
$table->enum('mode', ['replace', 'append', 'override'])->default('override');
|
||||
$table->json('params')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('linker_relations');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLinkersTable extends Migration
|
||||
{
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('linkers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title')->comment('链接标题');
|
||||
$table->string('type', 50)->comment('链接类型');
|
||||
$table->string('url')->comment('链接地址');
|
||||
$table->json('params')->nullable()->comment('默认参数');
|
||||
$table->boolean('status')->default(0)->comment('状态');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('linkers');
|
||||
}
|
||||
|
||||
}
|
||||
51
modules/Linker/Http/Controllers/IndexController.php
Normal file
51
modules/Linker/Http/Controllers/IndexController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Http\Controllers;
|
||||
|
||||
use Encore\Admin\Controllers\AdminController;
|
||||
use Encore\Admin\Form;
|
||||
use Encore\Admin\Grid;
|
||||
use Modules\Linker\Models\Linker;
|
||||
|
||||
class IndexController extends AdminController
|
||||
{
|
||||
|
||||
protected $title = '链接管理';
|
||||
|
||||
protected array $status = [
|
||||
'on' => ['value' => 1, 'text' => '启用', 'color' => 'success'],
|
||||
'off' => ['value' => 0, 'text' => '禁用', 'color' => 'danger'],
|
||||
];
|
||||
|
||||
public function grid(): Grid
|
||||
{
|
||||
$grid = new Grid(new Linker());
|
||||
|
||||
$grid->column('title', '标题');
|
||||
$grid->column('type', '类型')->using(Linker::TYPES);
|
||||
$grid->column('url', '目标地址');
|
||||
$grid->column('params', '附加参数');
|
||||
$grid->column('status', '状态')->switch($this->status);
|
||||
$grid->column('created_at', '创建时间');
|
||||
$grid->column('updated_at', '更新时间');
|
||||
|
||||
return $grid;
|
||||
}
|
||||
|
||||
public function form(): Form
|
||||
{
|
||||
$form = new Form(new Linker());
|
||||
$form->text('title', '链接标题')->required();
|
||||
$form->select('type', '链接类型')
|
||||
->options(Linker::TYPES)
|
||||
->required();
|
||||
$form->text('url', '目标地址')->required();
|
||||
$form->keyValue('params', '附加参数');
|
||||
$form->switch('status', '状态')
|
||||
->states($this->status)
|
||||
->default(1);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
66
modules/Linker/Linker.php
Normal file
66
modules/Linker/Linker.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker;
|
||||
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class Linker
|
||||
{
|
||||
|
||||
protected static string $mainTitle = '链接管理';
|
||||
|
||||
/**
|
||||
* Notes : 模块初始化要做的一些操作
|
||||
* @Date : 2021/3/12 11:34 上午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
public static function install()
|
||||
{
|
||||
Artisan::call('migrate', [
|
||||
'--path' => 'modules/Linker/Database/Migrations',
|
||||
]);
|
||||
|
||||
self::createAdminMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 卸载模块的一些操作
|
||||
* @Date : 2021/3/12 11:35 上午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
public static function uninstall()
|
||||
{
|
||||
$menu = config('admin.database.menu_model');
|
||||
|
||||
$main = $menu::where('title', self::$mainTitle)->first();
|
||||
|
||||
$main->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 创建后台菜单
|
||||
* @Date : 2021/3/17 9:48 上午
|
||||
* @Author : < Jason.C >
|
||||
*/
|
||||
protected static function createAdminMenu()
|
||||
{
|
||||
$menu = config('admin.database.menu_model');
|
||||
|
||||
$main = $menu::create([
|
||||
'parent_id' => 0,
|
||||
'order' => 45,
|
||||
'title' => self::$mainTitle,
|
||||
'icon' => 'fa-bars',
|
||||
]);
|
||||
|
||||
$main->children()->createMany([
|
||||
[
|
||||
'order' => 0,
|
||||
'title' => '链接管理',
|
||||
'icon' => 'fa-bars',
|
||||
'uri' => 'linkers',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
102
modules/Linker/Models/Linker.php
Normal file
102
modules/Linker/Models/Linker.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Linker extends Model
|
||||
{
|
||||
|
||||
use Cachable,
|
||||
SoftDeletes;
|
||||
|
||||
protected $table = 'linkers';
|
||||
|
||||
protected $casts = [
|
||||
'params' => 'json',
|
||||
];
|
||||
|
||||
const TYPE_WEB = 'web';
|
||||
const TYPE_MINI = 'mini';
|
||||
const TYPE_APP_NAVIGATE_TO = 'navigateTo';
|
||||
const TYPE_APP_REDIRECT_TO = 'redirectTo';
|
||||
const TYPE_APP_RE_LAUNCH = 'reLaunch';
|
||||
const TYPE_APP_SWITCH_TAB = 'switchTab';
|
||||
const TYPE_APP_NAVIGATE_BACK = 'navigateBack';
|
||||
|
||||
const TYPES = [
|
||||
self::TYPE_WEB => '网页连接(web)',
|
||||
self::TYPE_MINI => '小程序中跳转',
|
||||
self::TYPE_APP_NAVIGATE_TO => 'APP内部页面转跳',
|
||||
self::TYPE_APP_REDIRECT_TO => '跳转内部页面(关闭当前页)',
|
||||
self::TYPE_APP_RE_LAUNCH => '跳转内部页面(关闭所有页面)',
|
||||
self::TYPE_APP_SWITCH_TAB => 'TAB跳转(关闭所有非TAB页面)',
|
||||
self::TYPE_APP_NAVIGATE_BACK => 'APP页面返回',
|
||||
];
|
||||
|
||||
const MODE_APPEND = 'append';
|
||||
const MODE_REPLACE = 'replace';
|
||||
const MODE_OVERRIDE = 'override';
|
||||
|
||||
const MODES = [
|
||||
self::MODE_APPEND => '追加',
|
||||
self::MODE_REPLACE => '替换',
|
||||
self::MODE_OVERRIDE => '覆盖',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes : 转换链接到实际输出
|
||||
* @Date : 2021/6/21 4:03 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param \Modules\Linker\Models\LinkerRelation $relation
|
||||
* @return array
|
||||
*/
|
||||
public function getResource(LinkerRelation $relation): array
|
||||
{
|
||||
$params = '';
|
||||
|
||||
if (is_array($this->params)) {
|
||||
if ($relation->params) {
|
||||
switch ($relation->mode) {
|
||||
case self::MODE_APPEND:
|
||||
$this->params = array_merge($this->params, $relation->params);
|
||||
break;
|
||||
case self::MODE_REPLACE:
|
||||
$this->params = array_replace($this->params, $relation->params);
|
||||
break;
|
||||
case self::MODE_OVERRIDE;
|
||||
$this->params = $relation->params;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$params = http_build_query($this->params);
|
||||
}
|
||||
|
||||
$data = [
|
||||
'path' => $this->url,
|
||||
'openType' => $this->type,
|
||||
'url' => $this->url,
|
||||
'params' => $params,
|
||||
];
|
||||
switch ($data['openType']) {
|
||||
case self::TYPE_WEB:
|
||||
$data['path'] = '';
|
||||
$data['url'] .= '?' . $data['params'];
|
||||
$data['params'] = '';
|
||||
break;
|
||||
case self::TYPE_APP_NAVIGATE_BACK:
|
||||
$data['path'] = '';
|
||||
$data['url'] = '';
|
||||
$data['params'] = '';
|
||||
break;
|
||||
default:
|
||||
$data['url'] = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
40
modules/Linker/Models/LinkerRelation.php
Normal file
40
modules/Linker/Models/LinkerRelation.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class LinkerRelation extends Model
|
||||
{
|
||||
|
||||
protected $table = 'linker_relations';
|
||||
|
||||
protected $casts = [
|
||||
'params' => 'json',
|
||||
];
|
||||
|
||||
/**
|
||||
* Notes : 隶属链接
|
||||
* @Date : 2021/6/18 4:47 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function linker(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Linker::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 链接对应的模型
|
||||
* @Date : 2021/6/22 2:11 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
*/
|
||||
public function model(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
}
|
||||
47
modules/Linker/Providers/LinkerServiceProvider.php
Normal file
47
modules/Linker/Providers/LinkerServiceProvider.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class LinkerServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string $moduleName
|
||||
*/
|
||||
protected string $moduleName = 'Linker';
|
||||
|
||||
/**
|
||||
* @var string $moduleNameLower
|
||||
*/
|
||||
protected string $moduleNameLower = 'linker';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
* @return array
|
||||
*/
|
||||
public function provides(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
51
modules/Linker/Providers/RouteServiceProvider.php
Normal file
51
modules/Linker/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string $moduleName
|
||||
*/
|
||||
protected string $moduleName = 'Linker';
|
||||
|
||||
/**
|
||||
* The module namespace to assume when generating URLs to actions.
|
||||
* @var string
|
||||
*/
|
||||
protected string $moduleNamespace = 'Modules\Linker\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
* Register any model bindings or pattern based filters.
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
* @return void
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapAdminRoutes();
|
||||
}
|
||||
|
||||
protected function mapAdminRoutes()
|
||||
{
|
||||
Route::as(config('admin.route.as'))
|
||||
->domain(config('admin.route.domain'))
|
||||
->middleware(config('admin.route.middleware'))
|
||||
->namespace($this->moduleNamespace)
|
||||
->prefix(config('admin.route.prefix'))
|
||||
->group(module_path($this->moduleName, 'Routes/admin.php'));
|
||||
}
|
||||
|
||||
}
|
||||
22
modules/Linker/README.md
Normal file
22
modules/Linker/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# 链接模块
|
||||
|
||||
## 1. 使用
|
||||
|
||||
### 1. 模型 Trait
|
||||
|
||||
```php
|
||||
use Modules\Linker\Traits\HasLinker;
|
||||
```
|
||||
|
||||
### 2. laravel-admin
|
||||
|
||||
自动增加三个字段,
|
||||
1. 选择链接地址
|
||||
2. 替换链接地址里的参数
|
||||
3. 参数替换模式
|
||||
|
||||
```php
|
||||
use Modules\Linker\Traits\WithLinker;
|
||||
|
||||
$this->withUrl($form,'字段名称');
|
||||
```
|
||||
10
modules/Linker/Routes/admin.php
Normal file
10
modules/Linker/Routes/admin.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Routing\Router;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::group([
|
||||
'as' => 'linker.',
|
||||
], function (Router $router) {
|
||||
$router->resource('linkers', 'IndexController');
|
||||
});
|
||||
123
modules/Linker/Traits/HasLinker.php
Normal file
123
modules/Linker/Traits/HasLinker.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Modules\Linker\Models\LinkerRelation;
|
||||
|
||||
trait HasLinker
|
||||
{
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $linker_id;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
public $linker_params;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public ?string $linker_mode;
|
||||
|
||||
/**
|
||||
* 处理对应模型中关于链接数据的处理
|
||||
* 模型请 use HasLinker
|
||||
*/
|
||||
public static function bootHasLinker()
|
||||
{
|
||||
self::saving(function ($model) {
|
||||
unset($model->attributes['linker_id']);
|
||||
unset($model->attributes['linker_params']);
|
||||
unset($model->attributes['linker_mode']);
|
||||
});
|
||||
self::saved(function ($model) {
|
||||
$model->saveWithUrl();
|
||||
});
|
||||
// 这里要注意,如果模型使用了缓存 (use GeneaLabs\LaravelModelCaching\Traits\Cachable)
|
||||
// 在表单实例化模型的时候 要使用 (new Model())->disableModelCaching()
|
||||
self::retrieved(function ($model) {
|
||||
if ($relation = $model->hasLinker()) {
|
||||
$model->attributes['linker_id'] = $relation->linker_id;
|
||||
$model->attributes['linker_params'] = $relation->params;
|
||||
$model->attributes['linker_mode'] = $relation->mode;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 处理当前模型多余的三个字段
|
||||
* @Date : 2021/6/22 2:10 下午
|
||||
* @Author : < Jason.C >
|
||||
* @param $value
|
||||
*/
|
||||
public function setLinkerIdAttribute($value)
|
||||
{
|
||||
$this->linker_id = $value;
|
||||
}
|
||||
|
||||
public function setLinkerParamsAttribute($value)
|
||||
{
|
||||
$this->linker_params = $value;
|
||||
}
|
||||
|
||||
public function setLinkerModeAttribute($value)
|
||||
{
|
||||
$this->linker_mode = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 外链入库
|
||||
* 在BOOT中触发
|
||||
*/
|
||||
public function saveWithUrl(): void
|
||||
{
|
||||
if ($this->linker_id) {
|
||||
LinkerRelation::updateOrCreate([
|
||||
'model_type' => get_class($this),
|
||||
'model_id' => $this->getKey(),
|
||||
], [
|
||||
'linker_id' => $this->linker_id,
|
||||
'mode' => $this->linker_mode,
|
||||
'params' => $this->linker_params,
|
||||
]);
|
||||
} elseif (!$this->linker_id && $this->hasLinker()) {
|
||||
$this->hasLinker()->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前模型的链接配置
|
||||
* @return null|LinkerRelation
|
||||
*/
|
||||
public function hasLinker(): ?LinkerRelation
|
||||
{
|
||||
return LinkerRelation::whereHasMorph(
|
||||
'model',
|
||||
[get_class($this)],
|
||||
function (Builder $query) {
|
||||
$query->where($this->getKeyName(), $this->getKey());
|
||||
}
|
||||
)->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes : 返回该模型的链接数组
|
||||
* @Date : 2021/6/22 2:08 下午
|
||||
* @Author : < Jason.C >
|
||||
* @return array|null
|
||||
*/
|
||||
public function getLinkerAttribute(): ?array
|
||||
{
|
||||
$relation = $this->hasLinker();
|
||||
if ($relation && $relation->linker && $relation->linker->status) {
|
||||
return $relation->linker->getResource($relation);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
31
modules/Linker/Traits/WithLinker.php
Normal file
31
modules/Linker/Traits/WithLinker.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Linker\Traits;
|
||||
|
||||
use Encore\Admin\Form;
|
||||
use Exception;
|
||||
use Modules\Linker\Models\Linker;
|
||||
|
||||
trait WithLinker
|
||||
{
|
||||
|
||||
public function withUrl(Form $form, string $label = '链接地址'): Form
|
||||
{
|
||||
try {
|
||||
$links = Linker::pluck('title', 'id');
|
||||
} catch (Exception $e) {
|
||||
$links = [0 => '无链接'];
|
||||
}
|
||||
|
||||
$form->divider('链接设置');
|
||||
$form->select('linker_id', $label)
|
||||
->options($links);
|
||||
$form->select('linker_mode', '参数模式')
|
||||
->options(Linker::MODES)
|
||||
->default(Linker::MODE_OVERRIDE);
|
||||
$form->keyValue('linker_params', '替换参数');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
}
|
||||
28
modules/Linker/composer.json
Normal file
28
modules/Linker/composer.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "uztech/linker-module",
|
||||
"description": "",
|
||||
"type": "laravel-module",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Yz-Leady",
|
||||
"email": "149307205@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"encore/laravel-admin": "^1.8",
|
||||
"jasonc/api": "^5.0.0",
|
||||
"genealabs/laravel-model-caching": "^0.11.3",
|
||||
"joshbrw/laravel-module-installer": "^2.0",
|
||||
"laravel/framework": "^8.5",
|
||||
"nwidart/laravel-modules": "^8.2"
|
||||
},
|
||||
"extra": {
|
||||
"module-dir": "modules"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Linker\\": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
15
modules/Linker/module.json
Normal file
15
modules/Linker/module.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "Linker",
|
||||
"alias": "linker",
|
||||
"description": "链接管理模块(重构版本)",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\Linker\\Providers\\LinkerServiceProvider"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": [],
|
||||
"version": "1.0.0",
|
||||
"author": "Leady"
|
||||
}
|
||||
Reference in New Issue
Block a user