This commit is contained in:
2023-03-08 09:16:04 +08:00
commit e78454540f
1318 changed files with 210569 additions and 0 deletions

4
modules/Linker/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.idea
vendor
.DS_Store
composer.lock

View File

@@ -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');
}
}

View File

@@ -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');
}
}

View 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
View 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',
],
]);
}
}

View 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;
}
}

View 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();
}
}

View 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 [];
}
}

View 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
View 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,'字段名称');
```

View 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');
});

View 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;
}
}

View 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;
}
}

View 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\\": ""
}
}
}

View 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"
}