阶段更新

This commit is contained in:
2023-01-12 14:47:38 +08:00
parent 088dd64b2f
commit 5b8901281c
626 changed files with 39326 additions and 12 deletions

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Api\Controllers\Area;
use App\Api\Controllers\Controller;
use App\Api\Resources\Area\AreaCodeResource;
use App\Models\AreaCode;
use Illuminate\Http\JsonResponse;
class AreaCodeController extends Controller
{
/**
* Notes: 查看提货码数据
*
* @Author: 玄尘
* @Date: 2023/1/12 11:03
* @param AreaCode $areaCode
* @return JsonResponse
*/
public function show(AreaCode $code)
{
return $this->success(new AreaCodeResource($code));
}
}

View File

@@ -39,16 +39,34 @@ class IndexController extends Controller
* @Date: 2023/1/11 15:42 * @Date: 2023/1/11 15:42
* @param Area $area * @param Area $area
*/ */
public function codes(Area $area, Request $request) public function codes(Request $request)
{ {
$status = $request->status ?? ''; $status = $request->status ?? '';
$area = Area::query()
->whereHas('areaClerks', function ($q) {
$q->where('user_id', Api::userId());
})
->first();
$codes = $area->areaCodes() $codes = $area->areaCodes()
->when($status, function ($q) use ($status) { ->when($status, function ($q) use ($status) {
$q->where('status', $status); $q->where('status', $status);
}) })
->paginate(); ->paginate();
return $this->success(new AreaCodeCollection($codes));
$release = $area->areaCodes()->count();
$data = [
'count' => [
'all' => $area->stocks()->sum('amount'),
'stock' => $area->stock,
'release' => $release,
'unrelease' => bcsub($area->stock, $release),
],
'codes' => new AreaCodeCollection($codes)
];
return $this->success($data);
} }
/** /**

View File

@@ -14,7 +14,8 @@ class AreaCodeCollection extends BaseCollection
'data' => $this->collection->map(function ($info) { 'data' => $this->collection->map(function ($info) {
return [ return [
'area_code' => $info->id, 'area_code' => $info->id,
'user' => new UserBaseResource($info->user), 'user' => $info->user ? new UserBaseResource($info->user) : "",
'code' => $info->code,
'status' => [ 'status' => [
'status' => $info->status, 'status' => $info->status,
'text' => $info->status_text, 'text' => $info->status_text,

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Api\Resources\Area;
use Illuminate\Http\Resources\Json\JsonResource;
class AreaCodeResource extends JsonResource
{
public function toArray($request): array
{
return [
'area_code_id' => $this->id,
'code' => $this->code,
'area' => new AreaFullResource($this->area),
];
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Api\Resources\Area;
use Illuminate\Http\Resources\Json\JsonResource;
class AreaFullResource extends JsonResource
{
public function toArray($request): array
{
return [
'area_id' => $this->id,
'title' => $this->title,
'stock' => $this->stock,
'province' => $this->province->name,
'city' => $this->city->name,
'district' => $this->district->name,
'full_address' => $this->getFullAddress(),
];
}
}

View File

@@ -8,7 +8,15 @@ Route::group([
'middleware' => config('api.route.middleware_auth'), 'middleware' => config('api.route.middleware_auth'),
], function (Router $router) { ], function (Router $router) {
$router->get('areas', 'IndexController@index'); $router->get('areas', 'IndexController@index');
$router->get('areas/{area}/codes', 'IndexController@codes'); $router->get('areas/codes', 'IndexController@codes');
$router->get('areas/{area}/generate', 'IndexController@generate'); $router->get('areas/generate', 'IndexController@generate');
});
Route::group([
'namespace' => 'Area',
'middleware' => config('api.route.middleware_auth'),
], function (Router $router) {
$router->get('areas/{code}/show', 'AreaCodeController@show');
}); });

View File

@@ -121,8 +121,11 @@ class Area extends Model
if (! $num) { if (! $num) {
throw new \Exception('缺少数量'); throw new \Exception('缺少数量');
} }
if ($this->stock < $num) {
throw new \Exception('可生成数量不足,您还可以释放'.$this->stock); $canStockNum = bcsub($this->stock, $this->areaCodes()->count());
if ($canStockNum < $num) {
throw new \Exception('可生成数量不足,您还可以释放'.$canStockNum);
} }
while ($num > 0) { while ($num > 0) {

View File

@@ -16,10 +16,11 @@ class AreaCode extends Model
const STATUS_USED = 1; const STATUS_USED = 1;
const STATUS = [ const STATUS = [
self::STATUS_INIT => '未使用', self::STATUS_INIT => '未提取',
self::STATUS_USED => '已使用', self::STATUS_USED => '已提取',
]; ];
/** /**
* Notes: 生成人-管理人 * Notes: 生成人-管理人
* *
@@ -32,5 +33,17 @@ class AreaCode extends Model
return $this->belongsTo(User::class); return $this->belongsTo(User::class);
} }
/**
* Notes: 设置使用
*
* @Author: 玄尘
* @Date: 2023/1/12 14:25
*/
public function used()
{
$this->status = self::STATUS_USED;
$this->save();
}
} }

View File

@@ -9,6 +9,7 @@ trait HasStatus
/** /**
* Notes : 获取状态字段,主模型可配置 $status_field * Notes : 获取状态字段,主模型可配置 $status_field
*
* @Date : 2021/3/16 4:34 下午 * @Date : 2021/3/16 4:34 下午
* @Author : < Jason.C > * @Author : < Jason.C >
* @return string * @return string
@@ -20,22 +21,34 @@ trait HasStatus
/** /**
* Notes : 获取各状态的名称 * Notes : 获取各状态的名称
*
* @Date : 2021/5/27 11:50 上午 * @Date : 2021/5/27 11:50 上午
* @Author : < Jason.C > * @Author : < Jason.C >
* @return string[] * @return string[]
*/ */
protected function getStatusMap(): array protected function getStatusMap(): array
{ {
return isset($this->status_map) && !empty($this->status_map) ? $this->status_map : [ $status_map = [
0 => '待审核', 0 => '待审核',
1 => '正常', 1 => '正常',
2 => '驳回', 2 => '驳回',
3 => '关闭', 3 => '关闭',
]; ];
$statusData = constant(get_class($this)."::STATUS");
if (isset($this->status_map) && ! empty($this->status_map)) {
$status_map = $this->status_map;
} elseif ($statusData) {
$status_map = $statusData;
}
return $status_map;
} }
/** /**
* 正常显示的数据 * 正常显示的数据
*
* @Author:<Mr.Wang> * @Author:<Mr.Wang>
* @Date :2021-04-09 * @Date :2021-04-09
* @param \Illuminate\Database\Eloquent\Builder $query * @param \Illuminate\Database\Eloquent\Builder $query
@@ -48,6 +61,7 @@ trait HasStatus
/** /**
* 不显示的数据 * 不显示的数据
*
* @Author :<Mr.Wang> * @Author :<Mr.Wang>
* @Date :2021-04-09 * @Date :2021-04-09
* @param \Illuminate\Database\Eloquent\Builder $query * @param \Illuminate\Database\Eloquent\Builder $query
@@ -60,10 +74,11 @@ trait HasStatus
/** /**
* Notes : 状态查询 * Notes : 状态查询
*
* @Date : 2021/6/28 10:25 上午 * @Date : 2021/6/28 10:25 上午
* @Author : < Jason.C > * @Author : < Jason.C >
* @param \Illuminate\Database\Eloquent\Builder $query * @param \Illuminate\Database\Eloquent\Builder $query
* @param int $status * @param int $status
* @return \Illuminate\Database\Eloquent\Builder * @return \Illuminate\Database\Eloquent\Builder
*/ */
public function scopeOfStatus(Builder $query, int $status): Builder public function scopeOfStatus(Builder $query, int $status): Builder
@@ -73,6 +88,7 @@ trait HasStatus
/** /**
* Notes : 获取状态的文本信息 * Notes : 获取状态的文本信息
*
* @Date : 2021/4/25 2:10 下午 * @Date : 2021/4/25 2:10 下午
* @Author : < Jason.C > * @Author : < Jason.C >
* @return string * @return string
@@ -80,7 +96,6 @@ trait HasStatus
public function getStatusTextAttribute(): string public function getStatusTextAttribute(): string
{ {
$map = $this->getStatusMap(); $map = $this->getStatusMap();
return $map[$this->{$this->getStatusField()}] ?? '未知'; return $map[$this->{$this->getStatusField()}] ?? '未知';
} }

88
modules/Cms/Cms.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
namespace Modules\Cms;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Facade;
class Cms extends Facade
{
protected static string $mainTitle = '内容管理';
/**
* Notes : 模块初始化要做的一些操作
* @Date : 2021/3/12 11:34 上午
* @Author : < Jason.C >
*/
public static function install()
{
Artisan::call('migrate', [
'--path' => 'modules/Cms/Database/Migrations',
]);
self::createAdminMenu();
}
/**
* Notes : 卸载模块的一些操作
* @Date : 2021/3/12 11:35 上午
* @Author : < Jason.C >
*/
public static function uninstall()
{
$menu = config('admin.database.menu_model');
$mains = $menu::where('title', self::$mainTitle)->get();
foreach ($mains as $main) {
$main->delete();
}
}
protected static function createAdminMenu()
{
$menu = config('admin.database.menu_model');
$main = $menu::create([
'parent_id' => 0,
'order' => 15,
'title' => self::$mainTitle,
'icon' => 'fa-wordpress',
]);
$main->children()->createMany([
[
'order' => 1,
'title' => '文章管理',
'icon' => 'fa-bars',
'uri' => 'cms/articles',
],
[
'order' => 2,
'title' => '单页管理',
'icon' => 'fa-newspaper-o',
'uri' => 'cms/pages',
],
[
'order' => 3,
'title' => '分类管理',
'icon' => 'fa-indent',
'uri' => 'cms/categories',
],
[
'order' => 4,
'title' => '标签管理',
'icon' => 'fa-tags',
'uri' => 'cms/tags',
],
[
'order' => 5,
'title' => '素材管理',
'icon' => 'fa-adjust',
'uri' => 'cms/storages',
],
]);
}
}

View File

@@ -0,0 +1,10 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| 模块名称
|--------------------------------------------------------------------------
*/
'name' => 'Cms',
];

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsArticleCategoryTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_article_category', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('article_id');
$table->unsignedBigInteger('category_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_article_category');
}
}

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsArticlesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_articles', function (Blueprint $table) {
$table->id();
$table->string('slug')->index()->nullable()->comment('唯一的别名');
$table->string('title');
$table->string('sub_title')->nullable()->comment('副标题');
$table->string('description')->nullable();
$table->string('cover')->nullable();
$table->json('pictures')->nullable();
$table->text('content');
$table->json('attachments')->nullable();
$table->boolean('status')->default(0);
$table->unsignedInteger('clicks')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_articles');
}
}

View File

@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsCategoriesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('parent_id')->index()->default(0);
$table->string('title');
$table->string('slug')->nullable();
$table->string('description')->nullable();
$table->string('cover')->nullable();
$table->json('pictures')->nullable();
$table->text('content')->nullable();
$table->integer('order')->default(0);
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_categories');
}
}

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsPagesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_pages', function (Blueprint $table) {
$table->id();
$table->string('slug')->index()->nullable()->comment('唯一的别名');
$table->string('title');
$table->string('sub_title')->nullable()->comment('副标题');
$table->string('description')->nullable();
$table->string('cover')->nullable();
$table->json('pictures')->nullable();
$table->text('content');
$table->json('attachments')->nullable();
$table->boolean('status')->default(0);
$table->unsignedInteger('clicks')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_pages');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsTaggableTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_taggable', function (Blueprint $table) {
$table->id();
$table->foreignId('tag_id')->index();
$table->morphs('taggable');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_taggable');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCmsTagsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_tags', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('定位名称');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_tags');
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCmsStoragesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('cms_storages', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('url')->nullable();
$table->string('cover');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_storages');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCmsLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('cms_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('article_id')->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('cms_logs');
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use App\Admin\Traits\WithUploads;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Illuminate\Support\Arr;
use Modules\Cms\Models\Article;
use Modules\Cms\Models\Category;
use Modules\Cms\Models\Tag;
class ArticleController extends AdminController
{
use WithUploads;
protected $title = '文章管理';
public function grid(): Grid
{
$grid = new Grid(new Article());
$grid->model()->with('categories')->withCount('versions');
$grid->filter(function (Grid\Filter $filter) {
$filter->scope('trashed', '回收站')->onlyTrashed();
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->like('title', '文章标题');
$filter->like('slug', 'SLUG');
});
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->like('categories.title', '所属分类');
$filter->like('tags.name', '标签');
});
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->equal('status', '状态')->select(Article::getStatusMap());
});
});
$grid->column('id', '#ID#');
$grid->column('categories', '所属分类')->display(function ($categories) {
return Arr::pluck($categories, 'title');
})->label();
// $grid->column('tags')->pluck('name')->label('warning');
$grid->column('title', '文章标题');
// $grid->column('slug', 'SLUG');
$grid->column('status', '状态')->bool();
$grid->column('clicks', '浏览量');
$grid->column('versions_count', '历史版本')->link(function () {
return route('admin.cms.versions', [
'model' => get_class($this),
'key' => $this->id,
]);
}, '_self');
$grid->column('created_at', '创建时间');
return $grid;
}
/**
* Notes : 内容表单
* @Date : 2021/3/15 5:21 下午
* @Author : < Jason.C >
* @return \Encore\Admin\Form
*/
public function form(): Form
{
$form = new Form(new Article());
$form->text('title', '文章标题')
->rules([
'required',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
])
->required();
// $form->text('sub_title', '副标题')
// ->rules([
// 'nullable',
// 'max:255',
// ], [
// 'max' => '标题最大长度不能超过 :max 个字符',
// ]);
// $form->text('slug', '英文别名')
// ->rules([
// 'nullable',
// 'alpha_dash',
// ], [
// 'alpha_dash' => '别名中包含非法字符',
// ])
// ->help('字母、数字、下划线组成用来展示简短的URL');
$form->multipleSelect('categories', '所属分类')
->options(Category::selectOptions(function ($model) {
return $model->where('status', 1);
}, '请选择文章分类'))
->required();
// $form->multipleSelect('tags', '内容标签')
// ->options(function () {
// return Tag::pluck('name', 'id');
// });
$this->cover($form);
// $this->pictures($form);
$form->textarea('description', '文章简介')
->rules([
'nullable',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
]);
$form->ueditor('content', '文章内容')
->rules([
'required',
], [
'required' => '文章内容不能为空',
])
->required();
$this->attachments($form);
$form->switch('status', '状态')
->default(1);
return $form;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use App\Admin\Traits\WithUploads;
use Closure;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Row;
use Encore\Admin\Tree;
use Encore\Admin\Widgets\Box;
use Encore\Admin\Widgets\Form as WidgetsForm;
use Modules\Cms\Models\Category;
class CategoryController extends AdminController
{
use WithUploads;
protected $title = '分类管理';
public function grid(): Closure
{
return function (Row $row) {
$row->column(6, $this->treeView());
$row->column(6, function (Column $column) {
$form = new WidgetsForm();
$this->formData($form, true);
$form->action(route('admin.cms.categories.store'));
$column->append((new Box('新增分类', $form))->style('success'));
});
};
}
protected function treeView(): Tree
{
return Category::tree(function (Tree $tree) {
$tree->disableCreate();
$tree->branch(function ($branch) {
if ($branch['status'] == 1) {
$payload = "<i class='fa fa-eye text-primary'></i> ";
} else {
$payload = "<i class='fa fa-eye text-gray'></i> ";
}
$payload .= " [ID:{$branch['id']}] - ";
$payload .= " <strong>{$branch['title']}</strong> ";
return $payload;
});
});
}
protected function form(): Form
{
$form = new Form(new Category);
$this->formData($form);
return $form;
}
private function formData($form, $hideContent = false)
{
$form->select('parent_id', '上级分类')
->options(Category::selectOptions(function ($model) {
return $model->where('status', 1);
}, '一级分类'))
->required();
$form->text('title', '分类名称')
->rules('required');
$form->text('slug', '英文别名')
->rules([
'nullable',
'alpha_dash',
], [
'alpha_dash' => '别名中包含非法字符',
])
->help('字母、数字、下划线组成用来展示简短的URL');
$form->textarea('description', '分类简介')
->rules('nullable');
$this->cover($form);
$this->pictures($form);
$form->number('order', '排序')->default(0);
if (!$hideContent) {
$form->ueditor('content', '分类内容');
}
$form->switch('status', '状态')->default(1);
}
}

View File

@@ -0,0 +1,124 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use App\Admin\Traits\WithUploads;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Modules\Cms\Models\Page;
use Modules\Cms\Models\Tag;
class PageController extends AdminController
{
use WithUploads;
protected $title = '单页管理';
public function grid(): Grid
{
$grid = new Grid(new Page());
$grid->model()->withCount('versions');
$grid->filter(function (Grid\Filter $filter) {
$filter->scope('trashed', '回收站')->onlyTrashed();
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->like('title', '页面标题');
$filter->like('tags.name', '标签');
});
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->like('slug', 'SLUG');
});
$filter->column(1 / 3, function (Grid\Filter $filter) {
$filter->equal('status', '状态')->select(Page::getStatusMap());
});
});
$grid->column('id', '#ID#');
$grid->column('title', '页面标题');
$grid->column('tags')->pluck('name')->label('warning');
$grid->column('slug', '英文别名');
$grid->column('status', '状态')->bool();
$grid->column('clicks', '浏览量');
$grid->column('versions_count', '历史版本')->link(function () {
return route('admin.cms.versions', [
'model' => get_class($this),
'key' => $this->id,
]);
}, '_self');
$grid->column('created_at', '创建时间');
return $grid;
}
/**
* Notes : 内容表单
* @Date : 2021/3/15 5:21 下午
* @Author : < Jason.C >
* @return \Encore\Admin\Form
*/
public function form(): Form
{
$form = new Form(new Page());
$form->text('title', '页面标题')
->rules([
'required',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
])
->required();
$form->text('sub_title', '副标题')
->rules([
'nullable',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
]);
$form->text('slug', '英文别名')
->rules([
'nullable',
'alpha_dash',
], [
'alpha_dash' => '别名中包含非法字符',
])
->help('字母、数字、下划线组成用来展示简短的URL');
$form->multipleSelect('tags', '页面标签')
->options(function () {
return Tag::pluck('name', 'id');
});
$this->cover($form);
$this->pictures($form);
$form->textarea('description', '页面简介')
->rules([
'nullable',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
]);
$form->ueditor('content', '页面内容')
->rules([
'required',
], [
'required' => '页面内容不能为空',
])
->required();
$this->attachments($form);
$form->switch('status', '状态')
->default(1);
return $form;
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use App\Admin\Traits\WithUploads;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Modules\Cms\Models\Storage;
class StorageController extends AdminController
{
use WithUploads;
protected $title = '素材管理';
public function grid(): Grid
{
$grid = new Grid(new Storage());
$grid->column('id', '#ID#');
$grid->column('name', '素材标题');
$grid->column('地址')->display(function () {
return $this->cover_text;
});
return $grid;
}
public function form(): Form
{
$form = new Form(new Storage());
$form->text('name', '素材标题')
->rules([
'required',
'max:255',
], [
'max' => '标题最大长度不能超过 :max 个字符',
])
->required();
$this->cover($form);
$form->url('url', '素材地址');
return $form;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Modules\Cms\Models\Tag;
class TagController extends AdminController
{
protected $title = '标签管理';
public function grid(): Grid
{
$grid = new Grid(new Tag());
$grid->model()
->withCount(['articles', 'pages'])
->orderByDesc('id');
$grid->filter(function (Grid\Filter $filter) {
$filter->scope('trashed', '回收站')->onlyTrashed();
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('name', '标签名称');
});
});
$grid->column('name', '标签名称');
$grid->column('articles_count');
$grid->column('pages_count');
$grid->column('created_at', '创建时间');
return $grid;
}
public function form(): Form
{
$form = new Form(new Tag());
$form->text('name', '标签名称');
return $form;
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Modules\Cms\Http\Controllers\Admin;
use Encore\Admin\Auth\Database\Administrator;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Routing\Controller;
use Overtrue\LaravelVersionable\Version;
class VersionController extends Controller
{
public function index(Content $content, $model, $key): Content
{
return $content
->header($model . ' => ' . $key)
->description('数据操作日志')
->body($this->grid($model, $key));
}
public function grid($model, $key): Grid
{
$grid = new Grid(new Version());
$grid->disableCreateButton();
$grid->disableActions();
$grid->disableTools();
$grid->model()->whereHasMorph(
'versionable',
$model,
function (Builder $query) use ($key) {
$query->where('id', $key);
}
)->orderByDesc('id');
$grid->column('操作用户')->display(function () {
if ($this->user_id < config('mall.administrator_max_id')) {
config(['versionable.user_model' => Administrator::class]);
return '[Admin] ' . ($this->user->name ?? '--SYSTEM--');
} else {
return '[USER] ' . ($this->user->username ?? '--USER--');
}
});
$grid->column('versionable_type', '数据变动')->expand(function () {
$data = [];
foreach ($this->contents as $key => $item) {
$data[] = [
$key,
is_array($item) ? json_encode($item, JSON_UNESCAPED_UNICODE) : $item,
];
}
return new Table(['字段名称', '变更值'], $data);
});
$grid->column('操作时间')->display(function () {
return $this->created_at->toDateTimeString();
});
return $grid;
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Modules\Cms\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\Cms\Http\Resources\ArticleCollection;
use Modules\Cms\Http\Resources\ArticleResource;
use Modules\Cms\Models\Article;
class ArticleController extends Controller
{
/**
* Notes : 文章列表
*
* @Date : 2021/4/16 10:45 上午
* @Author : < Jason.C >
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
$categoryId = $request->category_id;
$title = $request->title;
$subTitle = $request->sub_title;
$slug = $request->slug;
$tagId = $request->tag_id;
$result = Article::query()
->when($title, function ($query) use ($title) {
$query->where('title', 'like', "%{$title}%");
})
->when($subTitle, function ($query) use ($subTitle) {
$query->where('sub_title', 'like', "%{$subTitle}%");
})
->when($slug, function ($query) use ($slug) {
$query->where('slug', 'like', "%{$slug}%");
})
->when($categoryId, function ($query) use ($categoryId) {
$query->whereHas('categories', function ($cate) use ($categoryId) {
$cate->where('category_id', $categoryId);
});
})
->when($tagId, function ($query) use ($tagId) {
$query->whereHas('tags', function ($tag) use ($tagId) {
$tag->where('tag_id', $tagId);
});
})
->where('status', 1)
->with(['categories', 'tags'])
->paginate(10);
return $this->success(new ArticleCollection($result));
}
/**
* Notes : 文章详情
*
* @Date : 2021/4/16 10:45 上午
* @Author : < Jason.C >
* @param Article $article
* @return mixed
*/
public function show(Article $article)
{
$article->read(Api::userId());
return $this->success(new ArticleResource($article));
}
/**
* Notes: 收藏/取消收藏
*
* @Author: 玄尘
* @Date: 2022/10/11 9:59
*/
public function favorite(Article $article): JsonResponse
{
$user = Api::user();
$user->toggleFavorite($article);
return $this->success([
'count' => $article->favorites()->count(),
'favorite' => $user->hasFavorited($article),
]);
}
/**
* Notes: 点赞/取消点赞
*
* @Author: 玄尘
* @Date: 2022/10/11 10:18
* @param Article $article
* @return JsonResponse
* @throws \Exception
*/
public function subscribe(Article $article): JsonResponse
{
$user = Api::user();
$user->toggleSubscribe($article);
return $this->success([
'count' => $article->subscribers()->count(),
'subscribed' => $user->hasSubscribed($article),
]);
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace Modules\Cms\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Cms\Http\Resources\CategoryCollection;
use Modules\Cms\Http\Resources\CategoryResource;
use Modules\Cms\Models\Category;
class CategoryController extends Controller
{
/**
* Notes : 分类首页
* @Date : 2021/4/19 9:29 上午
* @Author : < Jason.C >
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function index(Request $request)
{
$parentId = $request->get('parent_id', 0);
if (!is_integer($parentId)) {
return $this->failed('The param must be integer');
}
$result = Category::where('parent_id', $parentId)
->where('status', 1)
->orderBy('order', 'asc')
->get();
return $this->success(new CategoryCollection($result));
}
/**
* Notes : 分类的详情
* @Date : 2021/4/19 9:29 上午
* @Author : < Jason.C >
* @param \Modules\Cms\Models\Category $category
* @return mixed
*/
public function show(Category $category)
{
return $this->success(new CategoryResource($category));
}
}

View File

@@ -0,0 +1,105 @@
<?php
namespace Modules\Cms\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Cms\Http\Resources\PageCollection;
use Modules\Cms\Http\Resources\PageResource;
use Modules\Cms\Models\Page;
class PageController extends Controller
{
/**
* Notes : 单页列表
*
* @Date : 2021/4/16 10:45 上午
* @Author : < Jason.C >
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function index(Request $request)
{
$title = $request->title;
$subTitle = $request->sub_title;
$slug = $request->slug;
$tagId = $request->tag_id;
$result = Page::when($title, function ($query) use ($title) {
$query->where('title', 'like', "%{$title}%");
})->when($subTitle, function ($query) use ($subTitle) {
$query->where('sub_title', 'like', "%{$subTitle}%");
})->when($slug, function ($query) use ($slug) {
$query->where('slug', 'like', "%{$slug}%");
})->when($tagId, function ($query) use ($tagId) {
$query->whereHas('tags', function ($tag) use ($tagId) {
$tag->where('tag_id', $tagId);
});
})->where('status', 1)->with(['tags'])->paginate();
$result = new PageCollection($result);
return $this->success($result);
}
/**
* Notes : 单页详情
*
* @Date : 2021/4/16 11:25 上午
* @Author : < Jason.C >
* @param \Modules\Cms\Models\Page $page
* @return mixed
*/
public function show(Page $page)
{
$page->incrementClicks();
return $this->success(new PageResource($page));
}
/**
* Notes: 隐私条款
*
* @Author: 玄尘
* @Date: 2022/8/29 11:59
*/
public function secret()
{
$info = Page::where('slug', 'secret')->first();
$info->incrementClicks();
return $this->success(new PageResource($info));
}
/**
* Notes: 服务协议
*
* @Author: 玄尘
* @Date: 2022/8/29 12:00
* @return \Illuminate\Http\JsonResponse
*/
public function protocol()
{
$info = Page::where('slug', 'protocol')->first();
$info->incrementClicks();
return $this->success(new PageResource($info));
}
/**
* Notes: 授权书
*
* @Author: 玄尘
* @Date: 2022/12/30 14:16
* @return \Illuminate\Http\JsonResponse
*/
public function letter()
{
$info = Page::where('slug', 'letter')->first();
$info->incrementClicks();
return $this->success(new PageResource($info));
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Modules\Cms\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Cms\Http\Resources\TagCollection;
use Modules\Cms\Http\Resources\TagResource;
use Modules\Cms\Models\Tag;
class TagController extends Controller
{
/**
* Notes : 标签列表
* @Date : 2021/4/25 1:31 下午
* @Author : < Jason.C >
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function index(Request $request)
{
$name = $request->name;
$tags = Tag::when($name, function ($query) use ($name) {
$query->where('name', 'like', "%{$name}%");
})->orderByDesc('id')->paginate();
return $this->success(new TagCollection($tags));
}
public function show(Tag $tag)
{
return $this->success(new TagResource($tag));
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ArticleBaseResource extends JsonResource
{
public function toArray($request): array
{
return [
'article_id' => $this->id,
'title' => $this->title,
// 'sub_title' => $this->sub_title,
'description' => $this->description,
// 'slug' => $this->slug,
'categories' => CategoryBaseResource::collection($this->categories),
'tags' => TagResource::collection($this->tags),
'cover' => $this->cover_url,
'pictures' => $this->pictures_url,
'clicks' => $this->clicks,
'favorites' => $this->favorites()->count(),
'subscribes' => $this->subscribers()->count(),
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class ArticleCollection extends ResourceCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($article) {
return new ArticleBaseResource($article);
}),
'page' => $this->page(),
];
}
protected function page(): array
{
return [
'current' => $this->currentPage(),
'total_page' => $this->lastPage(),
'per_page' => $this->perPage(),
'has_more' => $this->hasMorePages(),
'total' => $this->total(),
];
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use Jason\Api\Api;
class ArticleResource extends JsonResource
{
public function toArray($request): array
{
$user = Api::user();
return [
'article_id' => $this->id,
'title' => $this->title,
// 'sub_title' => $this->sub_title,
'description' => $this->description,
// 'slug' => $this->slug,
'categories' => CategoryBaseResource::collection($this->categories),
'tags' => TagResource::collection($this->tags),
'cover' => $this->cover_url,
'pictures' => $this->pictures_url,
'clicks' => $this->clicks,
'favorites' => $this->favorites()->count(),
'subscribes' => $this->subscribers()->count(),
'isFavorite' => $user && $this->isFavoritedBy($user),
'isSubscribed' => $user && $this->isSubscribedBy($user),
'content' => $this->content,
'attachments' => $this->attachments,
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CategoryBaseResource extends JsonResource
{
public function toArray($request): array
{
return [
'category_id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
];
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class CategoryCollection extends ResourceCollection
{
/**
* Notes :
* @Date : 2021/4/25 1:32 下午
* @Author : < Jason.C >
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request): array
{
return $this->collection->map(function ($category) {
return [
'category_id' => $category->id,
'title' => $category->title,
'slug' => $category->slug,
'description' => $category->description,
'cover' => $category->cover_url,
'pictures' => $category->pictures_url,
'created_at' => (string) $category->created_at,
'children' => new self($category->children),
];
})->toArray();
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CategoryResource extends JsonResource
{
public function toArray($request): array
{
return [
'category_id' => $this->id,
'parent' => new self($this->parent),
'title' => $this->title,
'slug' => $this->slug,
'description' => $this->description,
'cover' => $this->cover_url,
'pictures' => $this->pictures_url,
'content' => $this->content,
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PageCollection extends ResourceCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($page) {
return [
'page_id' => $page->id,
'title' => $page->title,
'sub_title' => $page->sub_title,
'tags' => TagResource::collection($page->tags),
'description' => $page->description,
'slug' => $page->slug,
'cover' => $page->cover_url,
'pictures' => $page->pictures_url,
'clicks' => $page->clicks,
'created_at' => (string) $page->created_at,
];
}),
'page' => $this->page(),
];
}
protected function page(): array
{
return [
'current' => $this->currentPage(),
'total_page' => $this->lastPage(),
'per_page' => $this->perPage(),
'has_more' => $this->hasMorePages(),
'total' => $this->total(),
];
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class PageResource extends JsonResource
{
public function toArray($request): array
{
return [
'page_id' => $this->id,
'title' => $this->title,
'sub_title' => $this->sub_title,
'tags' => TagResource::collection($this->tags),
'description' => $this->description,
'slug' => $this->slug,
'cover' => $this->cover_url,
'pictures' => $this->pictures_url,
'clicks' => $this->clicks,
'content' => $this->content,
'attachments' => $this->attachments_url,
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class TagCollection extends ResourceCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($tag) {
return new TagResource($tag);
}),
'page' => $this->page(),
];
}
protected function page(): array
{
return [
'current' => $this->currentPage(),
'total_page' => $this->lastPage(),
'per_page' => $this->perPage(),
'has_more' => $this->hasMorePages(),
'total' => $this->total(),
];
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Modules\Cms\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class TagResource extends JsonResource
{
public function toArray($request): array
{
return [
'tag_id' => $this->id,
'name' => $this->name,
];
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use App\Traits\HasClicks;
use App\Traits\HasCovers;
use App\Traits\HasStatus;
use App\Traits\OrderByIdDesc;
use Encore\Admin\Traits\Resizable;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Modules\Cms\Traits\HasTags;
use Modules\Task\Facades\TaskFacade;
use Modules\Task\Models\Task;
use Overtrue\LaravelFavorite\Traits\Favoriteable;
use Overtrue\LaravelSubscribe\Traits\Subscribable;
use Overtrue\LaravelVersionable\Versionable;
class Article extends Model
{
use Cachable,
HasClicks,
HasCovers,
HasTags,
Subscribable,
Favoriteable,
HasStatus,
OrderByIdDesc,
Resizable,
Versionable,
SoftDeletes;
protected $table = 'cms_articles';
protected $casts = [
'pictures' => 'json',
'attachments' => 'json',
];
/**
* 不参与版本记录的字段
*
* @var array|string[]
*/
protected array $dontVersionable = ['clicks', 'updated_at'];
/**
* Notes: 阅读记录
*
* @Author: 玄尘
* @Date: 2022/10/20 9:57
* @return HasMany
*/
public function logs(): HasMany
{
return $this->hasMany(Log::class);
}
/**
* Notes: 阅读
*
* @Author: 玄尘
* @Date: 2022/10/20 9:57
* @param int $user_id
*/
public function read($user_id = '')
{
$this->incrementClicks();
if ($user_id) {
$this->logs()->create([
'user_id' => $user_id
]);
if (Task::query()->shown()->where('key', 'tour_article')->first()) {
# todo 阅读得水滴
TaskFacade::do('tour_article', $user_id);
}
if (Task::query()->shown()->where('key',
'read_article')->first() && $this->categories()->Health()->first()) {
# todo 阅读100次得水滴
TaskFacade::do('read_article', $user_id);
}
}
}
/**
* Notes : 文章所属分类
*
* @Date : 2021/4/15 12:44 下午
* @Author : < Jason.C >
* @return BelongsToMany
*/
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'cms_article_category')
->using(ArticleCategory::class)
->withTimestamps();
}
/**
* Notes : 获取附件的下载地址
*
* @Date : 2021/4/16 12:01 下午
* @Author : < Jason.C >
* @return Collection
*/
public function getAttachmentsUrlAttribute(): Collection
{
return collect($this->attachments)->map(function ($item) {
return Storage::url($item);
});
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Modules\Cms\Models;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ArticleCategory extends Pivot
{
public $incrementing = true;
public $table = 'cms_article_category';
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use App\Traits\HasCovers;
use Encore\Admin\Traits\AdminBuilder;
use Encore\Admin\Traits\ModelTree;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Overtrue\LaravelVersionable\Versionable;
class Category extends Model
{
use AdminBuilder,
Cachable,
HasCovers,
ModelTree,
Versionable,
SoftDeletes;
protected $table = 'cms_categories';
protected $casts = [
'pictures' => 'json',
];
/**
* 不参与版本记录的字段
*
* @var array|string[]
*/
protected array $dontVersionable = ['updated_at'];
public function children(): HasMany
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* Notes : 分类下的文章
*
* @Date : 2021/4/15 12:47 下午
* @Author : < Jason.C >
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function articles(): BelongsToMany
{
return $this->belongsToMany(Article::class, (new ArticleCategory())->getTable())
->using(ArticleCategory::class)
->withTimestamps();
}
/**
* Notes: 健康文章
*
* @Author: 玄尘
* @Date: 2022/10/31 10:05
*/
public function scopeHealth(Builder $query): Builder
{
return $query->where('slug', 'HEALTH');
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use Modules\User\Traits\BelongsToUser;
class Log extends Model
{
use BelongsToUser;
protected $table = 'cms_logs';
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use App\Traits\HasClicks;
use App\Traits\HasCovers;
use App\Traits\HasStatus;
use App\Traits\OrderByIdDesc;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Modules\Cms\Traits\HasTags;
use Overtrue\LaravelVersionable\Versionable;
class Page extends Model
{
use Cachable,
HasClicks,
HasCovers,
HasTags,
HasStatus,
OrderByIdDesc,
Versionable,
SoftDeletes;
protected $table = 'cms_pages';
protected $casts = [
'pictures' => 'json',
'attachments' => 'json',
];
/**
* 不参与版本记录的字段
* @var array|string[]
*/
protected array $dontVersionable = ['updated_at'];
/**
* Notes : 获取附件的下载地址
* @Date : 2021/4/16 12:01 下午
* @Author : < Jason.C >
* @return \Illuminate\Support\Collection
*/
public function getAttachmentsUrlAttribute(): Collection
{
return collect($this->attachments)->map(function ($item) {
return Storage::url($item);
});
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use App\Traits\HasCovers;
class Storage extends Model
{
use HasCovers;
protected $table = 'cms_storages';
public function getCoverTextAttribute()
{
if ($this->url) {
return $this->url . '/' . $this->cover;
} else {
return $this->cover_url;
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Cms\Models;
use App\Models\Model;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Tag extends Model
{
use Cachable,
SoftDeletes;
protected $table = 'cms_tags';
/**
* 不参与版本记录的字段
* @var array|string[]
*/
protected array $dontVersionable = ['updated_at'];
public function articles(): MorphToMany
{
return $this->morphedByMany(Article::class, 'taggable', 'cms_taggable');
}
public function pages(): MorphToMany
{
return $this->morphedByMany(Page::class, 'taggable', 'cms_taggable');
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Modules\Cms\Models;
use Illuminate\Database\Eloquent\Relations\MorphPivot;
class Taggable extends MorphPivot
{
public $incrementing = true;
protected $table = 'cms_taggable';
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Modules\Cms\Providers;
use Illuminate\Support\ServiceProvider;
class CmsServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected string $moduleName = 'Cms';
/**
* @var string $moduleNameLower
*/
protected string $moduleNameLower = 'cms';
/**
* 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->registerConfig();
$this->app->register(RouteServiceProvider::class);
}
/**
* Register config.
* @return void
*/
protected function registerConfig()
{
$this->publishes([
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
], 'config');
$this->mergeConfigFrom(
module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
);
}
/**
* Get the services provided by the provider.
* @return array
*/
public function provides(): array
{
return [];
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Cms\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected string $moduleName = 'Cms';
/**
* The module namespace to assume when generating URLs to actions.
* @var string
*/
protected string $moduleNamespace = 'Modules\Cms\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();
$this->mapApiRoutes();
}
protected function mapApiRoutes()
{
Route::as(config('api.route.as'))
->domain(config('api.route.domain'))
->middleware(config('api.route.middleware'))
->namespace($this->moduleNamespace)
->prefix(config('api.route.prefix'))
->group(module_path($this->moduleName, 'Routes/api.php'));
}
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'));
}
}

View File

@@ -0,0 +1,17 @@
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::group([
'prefix' => 'cms',
'namespace' => 'Admin',
'as' => 'cms.',
], function (Router $router) {
$router->resource('articles', 'ArticleController');
$router->resource('pages', 'PageController');
$router->resource('categories', 'CategoryController');
$router->resource('tags', 'TagController');
$router->resource('storages', 'StorageController');
$router->get('versions/{model}/{key}', 'VersionController@index')->name('versions');
});

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::group([
'prefix' => 'cms',
'namespace' => 'Api',
'middleware' => config('api.route.middleware_guess'),
], function (Router $router) {
$router->get('articles', 'ArticleController@index');
$router->get('articles/{article}', 'ArticleController@show');
$router->get('pages', 'PageController@index');
$router->get('pages/secret', 'PageController@secret');
$router->get('pages/protocol', 'PageController@protocol');
$router->get('pages/letter', 'PageController@letter');
$router->get('pages/{page}', 'PageController@show');
$router->get('categories', 'CategoryController@index');
$router->get('categories/{category}', 'CategoryController@show');
$router->get('tags', 'TagController@index');
$router->get('tags/{tag}', 'TagController@show');
});
Route::group([
'prefix' => 'cms',
'namespace' => 'Api',
'middleware' => config('api.route.middleware_auth'),
], function (Router $router) {
$router->get('articles/favorite/{article}', 'ArticleController@favorite');//收藏、取消收藏
$router->get('articles/subscribe/{article}', 'ArticleController@subscribe');//点赞、取消点赞
});

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Cms\Traits;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Modules\Cms\Models\Tag;
use Modules\Cms\Models\Taggable;
trait HasTags
{
/**
* Notes : 拥有内容标签
* @Date : 2021/4/25 12:58 下午
* @Author : < Jason.C >
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
public function tags(): MorphToMany
{
return $this->morphToMany(Tag::class, 'taggable', 'cms_taggable')
->using(Taggable::class)
->withTimestamps();
}
}

34
modules/Cms/composer.json Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "uztech/cms-module",
"description": "内容模块",
"type": "laravel-module",
"authors": [
{
"name": "Jason.Chen",
"email": "chenjxlg@163.com"
}
],
"require": {
"php": "^7.3|^8.0",
"encore/laravel-admin": "^1.8",
"genealabs/laravel-model-caching": "^0.11.3",
"jasonc/api": "^5.0.0",
"joshbrw/laravel-module-installer": "^2.0",
"laravel/framework": "^8.5",
"nwidart/laravel-modules": "^8.2",
"overtrue/laravel-versionable": "^2.6"
},
"extra": {
"module-dir": "modules",
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Cms\\": ""
}
}
}

15
modules/Cms/module.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "Cms",
"alias": "cms",
"description": "内容管理模块",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\Cms\\Providers\\CmsServiceProvider"
],
"aliases": {},
"files": [],
"requires": [],
"version": "1.0.0",
"author": "Jason.Chen"
}

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

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

View File

@@ -0,0 +1,168 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| 模块名称
|--------------------------------------------------------------------------
*/
'name' => 'Mall',
/*
|--------------------------------------------------------------------------
| 订单编号计数器位数,取值范围 6 - 16
|--------------------------------------------------------------------------
*/
'order_no_counter_length' => 8,
/*
|--------------------------------------------------------------------------
| 退款单编号前缀
|--------------------------------------------------------------------------
*/
'refund_no_counter_prefix' => 'RF',
/*
|--------------------------------------------------------------------------
| 退款单编号计数器位数,取值范围 6 - 16 - 退款编号前缀位数
|--------------------------------------------------------------------------
*/
'refund_no_counter_length' => 6,
/*
|--------------------------------------------------------------------------
| 商品规格的扩展属性
|--------------------------------------------------------------------------
*/
'sku_extends_attributes' => [
'market_fee' => '平台手续费',
],
'administrator_max_id' => 10000,
'workflow' => [
'orders' => [
'type' => 'state_machine',
'marking_store' => [
'type' => 'single_state',
'property' => 'currentState',
],
'supports' => [Modules\Mall\Models\Order::class],
'places' => [
'INIT',
'CANCEL',
'PAID',
'DELIVERED',
'SIGNED',
'COMPLETED',
'REFUND_APPLY',
'REFUND_AGREE',
'REFUND_REFUSE',
'REFUND_DELIVER',
'REFUND_DELIVERD',
'REFUND_PROCESS',
'REFUND_COMPLETED',
],
'transitions' => [
'cancel' => [
'from' => ['INIT', 'PAID'],
'to' => 'CANCEL',
],
'pay' => [
'from' => 'INIT',
'to' => 'PAID',
],
'deliver' => [
'from' => 'PAID',
'to' => 'DELIVERED',
],
'sign' => [
'from' => 'DELIVERED',
'to' => 'SIGNED',
],
'complete' => [
'from' => 'SIGNED',
'to' => 'COMPLETED',
],
'refund' => [
'from' => ['PAID', 'SIGNED'],
'to' => 'REFUND_APPLY',
],
'agree' => [
'from' => ['PAID', 'SIGNED', 'REFUND_APPLY'],
'to' => 'REFUND_AGREE',
],
'refuse' => [
'from' => 'REFUND_APPLY',
'to' => 'REFUND_REFUSE',
],
'user_deliver' => [
'from' => 'REFUND_AGREE',
'to' => 'REFUND_DELIVER',
],
'user_deliverd' => [
'from' => 'REFUND_DELIVER',
'to' => 'REFUND_DELIVERD',
],
'process' => [
'from' => ['REFUND_AGREE', 'REFUND_DELIVERD'],
'to' => 'REFUND_PROCESS',
],
'completed' => [
'from' => ['PAID', 'DELIVERED', 'SIGNED', 'REFUND_PROCESS', 'REFUND_DELIVERD'],
'to' => 'REFUND_COMPLETED',
],
],
],
'refunds' => [
'type' => 'state_machine',
'marking_store' => [
'type' => 'single_state',
'property' => 'currentState',
],
'supports' => [Modules\Mall\Models\Refund::class],
'places' => [
'REFUND_APPLY',
'REFUND_AGREE',
'REFUND_REFUSE',
'REFUND_PROCESS',
'REFUND_DELIVER',
'REFUND_DELIVERED',
'REFUND_SIGNED',
'REFUND_COMPLETED',
],
'transitions' => [
'agree' => [
'from' => 'REFUND_APPLY',
'to' => 'REFUND_AGREE',
],
'refuse' => [
'from' => 'REFUND_APPLY',
'to' => 'REFUND_REFUSE',
],
'deliver' => [
'from' => 'REFUND_AGREE',
'to' => 'REFUND_DELIVER',
],
'delivered' => [
'from' => 'REFUND_DELIVER',
'to' => 'REFUND_DELIVERED',
],
'sign' => [
'from' => 'REFUND_DELIVERED',
'to' => 'REFUND_SIGNED',
],
'process' => [
'from' => ['REFUND_AGREE', 'REFUND_SIGNED'],
'to' => 'REFUND_PROCESS',
],
'completed' => [
'from' => 'REFUND_PROCESS',
'to' => 'REFUND_COMPLETED',
],
],
],
],
];

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallAddressesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_addresses', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('user_id')->index();
$table->string('name', 32);
$table->string('mobile', 32);
$table->unsignedInteger('province_id');
$table->unsignedInteger('city_id');
$table->unsignedInteger('district_id');
$table->string('address');
$table->boolean('is_default')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_addresses');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallBannersTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_banners', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->default(0)->index()->comment('所属店铺');
$table->string('title');
$table->string('cover');
$table->integer('position')->unsigned();
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_banners');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallBrandsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_brands', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->string('name');
$table->string('cover')->nullable();
$table->string('description')->nullable();
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_brands');
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallCartsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_carts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('sku_id')->comment('加入购物车的商品条目');
$table->unsignedInteger('qty')->default(1)->comment('数量');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_carts');
}
}

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallCategoriesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_categories', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->unsignedBigInteger('parent_id')->default(0)->index()->comment('父级id');
$table->string('name');
$table->string('slug')->nullable();
$table->string('description')->nullable();
$table->string('cover')->nullable();
$table->integer('order')->default(0);
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_categories');
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallDeliveriesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_deliveries', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->string('name')->comment('模板名称');
$table->unsignedTinyInteger('type')->comment('计费方式1按件数 2按重量');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_deliveries');
}
}

View File

@@ -0,0 +1,40 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMallDeliveryRulesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mall_delivery_rules', function (Blueprint $table) {
$table->id();
$table->integer('delivery_id')->comment('配送模板id');
$table->json('regions')->nullable()->comment('可配送区域(城市id集)');
$table->decimal('first', 8, 2)->default(0)->comment('首件(个)/首重(Kg)');
$table->decimal('first_fee', 8, 2)->default(0)->comment('运费(元)');
$table->decimal('additional', 8, 2)->default(0)->comment('续件/续重');
$table->decimal('additional_fee', 8, 2)->default(0)->comment('续费(元)');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_delivery_rules');
}
}

View File

@@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use Modules\Mall\Database\Seeders\ExpressSeeder;
class CreateMallExpressesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_expresses', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->nullable()->comment('简称');
$table->string('cover')->nullable();
$table->string('description')->nullable();
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
Artisan::call('db:seed', [
'--class' => ExpressSeeder::class,
]);
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_expresses');
}
}

View File

@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallGoodsSkusTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_goods_skus', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('goods_id')->index();
$table->string('unit')->nullable()->comment('商品单元编号');
$table->string('cover')->nullable();
$table->decimal('price');
$table->decimal('score')->comment('积分/原石');
$table->decimal('assets', 8, 2)->comment('资产');
$table->integer('stock')->default(0);
$table->decimal('weight')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_goods_skus');
Schema::dropIfExists('mall_goods_sku_spec');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallGoodsSpecValuesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_goods_spec_values', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('spec_id')->index();
$table->string('value');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_goods_spec_values');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallGoodsSpecsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_goods_specs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('goods_id')->index();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_goods_specs');
}
}

View File

@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallGoodsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mall_goods', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->unsignedBigInteger('category_id')->index()->comment('分类');
$table->unsignedBigInteger('brand_id')->nullable()->index()->comment('品牌ID');
$table->unsignedBigInteger('delivery_id')->nullable()->comment('物流模板');
$table->unsignedTinyInteger('type')->default(1)->comment('规格类型');
$table->unsignedTinyInteger('pay_type')->default(1)->comment('支付方式');
$table->unsignedTinyInteger('deduct_stock_type')->default(1)->comment('库存扣减方式');
$table->unsignedTinyInteger('channel')->default(1)->comment('商品类型');
$table->boolean('status')->default(0);
$table->boolean('is_post_sale')->default(1)->comment('是否可以申请售后');
$table->unsignedInteger('clicks')->default(0)->comment('浏览量');
$table->unsignedInteger('sales')->default(0)->comment('总销量');
$table->decimal('original_price', 10, 2)->default(0)->comment('商品显示的原价');
$table->string('name');
$table->string('cover')->nullable();
$table->json('pictures')->nullable();
$table->string('description')->nullable();
$table->text('content')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_goods');
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallGoodsTagTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_goods_tag', function (Blueprint $table) {
$table->unsignedBigInteger('goods_id')->index();
$table->unsignedBigInteger('tag_id')->index();
$table->timestamps();
$table->primary(['goods_id', 'tag_id']);
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_goods_tag');
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallJobsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_jobs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index();
$table->string('name');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_jobs');
}
}

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallOrderExpressesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_order_expresses', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('order_id')->index();
$table->string('name', 32)->nullable();
$table->string('mobile', 32)->nullable();
$table->unsignedInteger('province_id')->index()->nullable();
$table->unsignedInteger('city_id')->index()->nullable();
$table->unsignedInteger('district_id')->index()->nullable();
$table->string('address')->nullable();
$table->unsignedBigInteger('express_id')->nullable()->comment('物流公司');
$table->string('express_no', 32)->nullable()->comment('物流单号');
$table->dateTime('deliver_at')->nullable()->comment('发货时间');
$table->dateTime('receive_at')->nullable()->comment('签收时间');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_order_expresses');
}
}

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallOrderItemsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_order_items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('order_id')->index('order_id');
$table->morphs('item');
$table->unsignedInteger('qty')->comment('数量');
$table->unsignedDecimal('price', 20, 2)->comment('单价');
$table->json('source')->nullable();
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_order_items');
}
}

View File

@@ -0,0 +1,49 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallOrdersTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_orders', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->string('order_no', 32)->unique()->comment('订单编号');
$table->unsignedInteger('user_id')->index()->comment('下单用户');
$table->unsignedDecimal('amount', 20, 2)->comment('订单金额');
$table->unsignedDecimal('freight', 10, 2)->default(0)->comment('运费');
$table->timestamp('expired_at')->nullable()->comment('订单过期时间');
$table->timestamp('paid_at')->nullable()->comment('支付时间');
$table->string('state', 16)->comment('状态')->nullable();
$table->boolean('type')->comment('订单类型1 正常 2试用');
$table->string('remark')->nullable()->comment('用户留言');
$table->string('description')->nullable()->comment('备注');
$table->json('source')->comment('附加数据')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_orders');
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallReasonsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_reasons', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->boolean('status')->default(0);
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('reasons');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallRefundExpressesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_refund_expresses', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->unsignedBigInteger('refund_id')->index()->comment('所属退款单');
$table->string('company')->nullable()->comment('退款物流');
$table->string('number')->nullable()->comment('退款单号');
$table->timestamp('deliver_at')->nullable()->comment('寄回时间');
$table->timestamp('receive_at')->nullable()->comment('收到时间');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_refund_expresses');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallRefundItemsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_refund_items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('refund_id')->index()->comment('所属退款单');
$table->unsignedBigInteger('order_id')->comment('所属订单');
$table->unsignedBigInteger('order_item_id')->comment('详情ID');
$table->unsignedInteger('qty')->comment('数量');
$table->unsignedDecimal('price', 20, 2)->comment('单价');
$table->json('source')->nullable();
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_refund_items');
}
}

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallRefundLogsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_refund_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('refund_id');
$table->morphs('userable');
$table->string('pictures')->nullable()->comment('图片');
$table->string('title')->nullable()->comment('原因');
$table->string('remark')->nullable()->comment('备注');
$table->string('state', 16)->comment('状态')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_tags');
}
}

View File

@@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallRefundsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_refunds', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->unsignedBigInteger('order_id')->index()->comment('所属订单');
$table->string('refund_no', 32)->comment('退款单号');
$table->unsignedBigInteger('user_id')->comment('下单用户');
$table->unsignedDecimal('refund_total', 20, 2)->comment('申请退款金额');
$table->unsignedDecimal('actual_total', 20, 2)->comment('实退金额');
$table->string('state', 16)->comment('状态')->nullable();
$table->string('remark')->nullable()->comment('备注');
$table->timestamp('refunded_at')->nullable()->comment('退款时间');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_refunds');
}
}

View File

@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use Modules\Mall\Database\Seeders\RegionSeeder;
class CreateMallRegionsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_regions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('parent_id')->index();
$table->string('name');
$table->boolean('depth');
});
Artisan::call('db:seed', [
'--class' => RegionSeeder::class,
]);
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_regions');
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallShopExpressTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_shop_express', function (Blueprint $table) {
$table->unsignedBigInteger('shop_id')->index();
$table->unsignedBigInteger('express_id')->index();
$table->timestamps();
$table->primary(['shop_id', 'express_id']);
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_shop_express');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMallShopReasonsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_shop_reasons', function (Blueprint $table) {
$table->unsignedBigInteger('shop_id')->index();
$table->unsignedBigInteger('reason_id')->index();
$table->timestamps();
$table->primary(['shop_id', 'reason_id']);
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_shop_reasons');
}
}

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallShopStaffersTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_shop_staffers', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index();
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('job_id')->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_shop_staffers');
}
}

View File

@@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallShopsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_shops', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('user_id')->index()->default(0);
$table->string('name');
$table->boolean('is_self')->unsigned()->default(0)->comment('是否自营');
$table->string('description')->nullable();
$table->string('mobile')->nullable();
$table->string('cover')->nullable();
$table->boolean('status')->default(0);
$table->unsignedInteger('province_id')->index()->default(0);
$table->unsignedInteger('city_id')->index()->default(0);
$table->unsignedInteger('district_id')->index()->default(0);
$table->string('address')->nullable();
$table->json('configs')->nullable();
$table->integer('order')->default(9999)->comment('排序用的,后台控制');
$table->string('reject_reason')->comment('驳回原因')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_shops');
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMallTagsTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('mall_tags', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('shop_id')->index()->comment('所属店铺');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_tags');
}
}

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMallActivitiesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mall_activities', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('description')->nullable();
$table->string('cover')->nullable();
$table->text('content')->nullable();
$table->boolean('status')->default(0);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_activities');
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddChannelToMallOrdersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('mall_orders', function (Blueprint $table) {
$table->boolean('channel')->default(1)->comment('渠道')->after('type');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('mall_orders', function (Blueprint $table) {
});
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTypeAndPersonToMallOrdersExpressesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('mall_order_expresses', function (Blueprint $table) {
$table->boolean('type')->default(1)->comment('方式')->after('receive_at');
$table->boolean('person')->nullable()->comment('经办人')->after('type');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('mall_orders_expresses', function (Blueprint $table) {
});
}
}

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMallVideosTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('mall_videos', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('cover')->nullable();
$table->string('path');
$table->boolean('status')->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('mall_videos');
}
}

Some files were not shown because too many files have changed in this diff Show More