4
0
Fork 0
vine_liutk 2022-07-28 17:51:58 +08:00
commit 538423073c
18 changed files with 408 additions and 186 deletions

193
README.md
View File

@ -1,193 +1,20 @@
# Dcat-Admin
<div align="center">
<img src="https://cdn.learnku.com/uploads/images/202009/27/38389/WFQxJ7qZ1k.png!large" height="80">
</div>
<br>
Fork From [jqhph/dcat-admin](https://github.com/jqhph/dcat-admin)
<p align="center">
<a href="https://github.com/jqhph/dcat-admin/actions">
<img src="https://github.com/jqhph/dcat-admin/workflows/Laravel%20Dusk/badge.svg" alt="Build Status">
</a>
<a href="https://styleci.io/repos/182349597">
<img src="https://github.styleci.io/repos/182349597/shield" alt="StyleCI">
</a>
<a href="https://packagist.org/packages/dcat/laravel-admin" ><img src="https://poser.pugx.org/dcat/laravel-admin/v/stable" /></a>
<a href="https://packagist.org/packages/dcat/laravel-admin"><img src="https://img.shields.io/packagist/dt/dcat/laravel-admin.svg?color=" /></a>
<a><img src="https://img.shields.io/badge/php-7.1+-59a9f8.svg?style=flat" /></a>
<a><img src="https://img.shields.io/badge/laravel-5.5+-59a9f8.svg?style=flat" ></a>
</p>
## 改动
<p align=""><code>Dcat Admin</code>是一个基于<a href="https://www.laravel-admin.org/" target="_blank">laravel-admin</a>二次开发而成的后台系统构建工具只需很少的代码即可快速构建出一个功能完善的高颜值后台系统。内置丰富的后台常用组件开箱即用让开发者告别冗杂的HTML代码对后端开发者非常友好。</p>
### Show
### 详细页-列表按钮点击跳转方式
- [官方网站](http://www.dcatadmin.com)
- [中文文档](https://learnku.com/docs/dcat-admin)
- [English documentions](http://www.dcatadmin.com/docs/en-2.x/quick-start.html)
- [Demo / 在线演示](http://103.39.211.179:8080/admin)
- [Demo源码](https://github.com/jqhph/dcat-admin-demo)
- [Demo源码 (码云)](https://gitee.com/jqhph/dcat-admin-demo)
- [扩展](#)
- `packages/dcat-admin/src/Show/Tools.php` 254行
![](https://cdn.learnku.com/uploads/images/202101/28/38389/YLmL7PLqH7.png!large)
### 功能特性
- [x] 简洁优雅、灵活可扩展的API
- [x] 用户管理
- [x] RBAC权限管理支持无限极权限节点
- [x] 菜单管理
- [x] 使用pjax构建无刷新页面支持**按需加载**静态资源,可以无限扩展组件而不影响整体性能
- [x] 松耦合的页面构建与数据操作设计,可轻松切换数据源
- [x] 自定义页面
- [x] 自定义主题配色
- [x] 多主题切换功能,内置多种主题色
- [x] 可轻松构建无菜单栏的独立页面(如可用于构建弹窗选择器等功能)
- [x] 插件功能
- [x] 可视化代码生成器,可根据数据表一键生成增删改查页面
- [x] 数据表格构建工具,内置丰富的表格常用功能(如组合表头、数据导出、搜索、快捷创建、批量操作等)
- [x] 树状表格功能构建工具,支持分页和点击加载
- [x] 数据表单构建工具,内置丰富的表单类型,支持表单异步提交
- [x] 分步表单构建工具
- [x] 弹窗表单构建工具
- [x] 数据详情页构建工具
- [x] 无限层级树状页面构建工具,支持用拖拽的方式实现数据的层级、排序等操作
- [x] 内置丰富的常用页面组件如图表、数据统计卡片、下拉菜单、Tab卡片、提示工具等
- [x] `Section`功能(类似`Wordpress`的`Filter`和`blade`模板的`section`标签)
- [x] 异步文件上传表单,支持分块多线程上传
- [x] 多应用
- [ ] 插件市场,只需在管理页面轻轻点击鼠标即可完成插件的安装、更新和卸载等操作
### 环境
- PHP >= 7.1.0
- Laravel 5.5.0 ~ 9.*
- Fileinfo PHP Extension
### 安装
> 如果安装过程中出现`composer`下载过慢或安装失败的情况,请运行命令`composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/`把`composer`镜像更换为阿里云镜像。
首先需要安装`laravel`框架,如已安装可以跳过此步骤。如果您是第一次使用`laravel`,请务必先阅读文档 [安装 《Laravel中文文档》](https://learnku.com/docs/laravel/8.x/installation/9354)
```bash
composer create-project --prefer-dist laravel/laravel 项目名称 7.*
# 或
composer create-project --prefer-dist laravel/laravel 项目名称
```html
<a href="{$this->getListPath()}" class="btn btn-sm btn-primary ">
```
安装完`laravel`之后需要修改`.env`文件,设置数据库连接设置正确
```dotenv
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dcat-admin
DB_USERNAME=root
DB_PASSWORD=
```html
<a href="javascript:window.history.back()" class="btn btn-sm btn-primary ">
```
安装`dcat-admin`
```
cd {项目名称}
composer require dcat/laravel-admin
```
然后运行下面的命令来发布资源:
```
php artisan admin:publish
```
在该命令会生成配置文件`config/admin.php`,可以在里面修改安装的地址、数据库连接、以及表名,建议都是用默认配置不修改。
然后运行下面的命令完成安装:
> 执行这一步命令可能会报以下错误`Specified key was too long ... 767 bytes`,如果出现这个报错,请在`app/Providers/AppServiceProvider.php`文件的`boot`方法中加上代码`\Schema::defaultStringLength(191);`,然后删除掉数据库中的所有数据表,再重新运行一遍`php artisan admin:install`命令即可。
```
php artisan admin:install
```
上述步骤操作完成之后就可以配置`web`服务了,**注意需要把`web`目录指向`public`目录**!如果用的是`nginx`,还需要在配置中加上伪静态配置
```dotenv
location / {
try_files $uri $uri/ /index.php?$query_string;
}
```
启动服务后,在浏览器打开 `http://localhost/admin`,使用用户名 `admin` 和密码 `admin`登陆。
<a name="extensions"></a>
### 扩展
| 扩展 | 描述 | dcat-admin 版本 |
| ------------------------------------------------ | ---------------------------------------- |---------------------------------------- |
| [mosiboom/dcat-iframe-tab](https://github.com/mosiboom/dcat-iframe-tab) | IFRAME TAB标签切换 | 2.x |
| [super-eggs/dcat-distpicker](https://github.com/super-eggs/dcat-distpicker) | 省市区联动 | 2.x |
| [ueditor](https://github.com/jqhph/dcat-admin-ueditor) | 百度在线编辑器 | 1.x |
| [grid-sortable](https://github.com/jqhph/dcat-admin-grid-sortable) | 表格拖曳排序工具 | 1.x |
### 鸣谢
`Dcat Admin` 基于以下组件:
+ [Laravel](https://laravel.com/)
+ [Laravel Admin](https://www.laravel-admin.org/)
+ [AdminLTE3](https://github.com/ColorlibHQ/AdminLTE)
+ [bootstrap4](https://getbootstrap.com/)
+ [jQuery3](https://jquery.com/)
+ [Eonasdan Datetimepicker](https://github.com/Eonasdan/bootstrap-datetimepicker/)
+ [font-awesome](http://fontawesome.io)
+ [jquery-form](https://github.com/jquery-form/form)
+ [moment](http://momentjs.com/)
+ [webuploader](http://fex.baidu.com/webuploader/)
+ [jquery-pjax](https://github.com/defunkt/jquery-pjax)
+ [Nestable](http://dbushell.github.io/Nestable/)
+ [toastr](http://codeseven.github.io/toastr/)
+ [editor-md](https://github.com/pandao/editor.md)
+ [fontawesome-iconpicker](https://github.com/itsjavi/fontawesome-iconpicker)
+ [layer弹出层](http://layer.layui.com/)
+ [char.js](https://www.chartjs.org)
+ [nprogress](https://ricostacruz.com/nprogress/)
+ [bootstrap-validator](https://github.com/1000hz/bootstrap-validator)
+ [Google map](https://www.google.com/maps)
+ [Tencent map](http://lbs.qq.com/)
### Contributors
#### Code Contributors
This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].
<a href="https://github.com/jqhph/dcat-admin/graphs/contributors"><img src="https://opencollective.com/dcat-admin/contributors.svg?width=890&button=false" /></a>
### Financial Contributors
Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/dcat-admin/contribute)]
#### Individuals
<a href="https://opencollective.com/dcat-admin"><img src="https://opencollective.com/dcat-admin/individuals.svg?width=890"></a>
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/dcat-admin/contribute)]
<a href="https://opencollective.com/dcat-admin/organization/0/website"><img src="https://opencollective.com/dcat-admin/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/1/website"><img src="https://opencollective.com/dcat-admin/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/2/website"><img src="https://opencollective.com/dcat-admin/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/3/website"><img src="https://opencollective.com/dcat-admin/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/4/website"><img src="https://opencollective.com/dcat-admin/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/5/website"><img src="https://opencollective.com/dcat-admin/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/6/website"><img src="https://opencollective.com/dcat-admin/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/7/website"><img src="https://opencollective.com/dcat-admin/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/8/website"><img src="https://opencollective.com/dcat-admin/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/dcat-admin/organization/9/website"><img src="https://opencollective.com/dcat-admin/organization/9/avatar.svg"></a>
### License
------------
`dcat-admin` is licensed under [The MIT License (MIT)](LICENSE).

7
packages/goods/.gitignore vendored 100644
View File

@ -0,0 +1,7 @@
.DS_Store
phpunit.phar
/vendor
composer.phar
composer.lock
*.project
.idea/

View File

@ -0,0 +1,3 @@
# Dcat Admin Extension

View File

@ -0,0 +1,31 @@
{
"name": "peidikeji/dcat-admin-extension-goods",
"alias": "goods",
"description": "基础商品管理",
"type": "library",
"keywords": ["dcat-admin", "extension"],
"homepage": "https://github.com/peidikeji/goods",
"license": "MIT",
"authors": [
{
"name": "panliang",
"email": "1163816051@qq.com"
}
],
"require": {
"php": ">=7.1.0"
},
"autoload": {
"psr-4": {
"Peidikeji\\Goods\\": "src/"
}
},
"extra": {
"dcat-admin": "Peidikeji\\Goods\\GoodsServiceProvider",
"laravel": {
"providers": [
"Peidikeji\\Goods\\GoodsServiceProvider"
]
}
}
}

View File

@ -0,0 +1,4 @@
<?php
return [
];

View File

@ -0,0 +1,21 @@
<?php
return [
'labels' => [
'GoodsCategory' => '商品分类',
'goods' => '商品管理',
'category' => '分类管理',
'root' => '无',
],
'fields' => [
'name' => '分类名称',
'image' => '图片',
'description' => '描述',
'sort' => '排序(正序)',
'parent_id' => '上级',
'is_enable' => '开启',
'parent' => [
'name' => '上级'
]
]
];

View File

@ -0,0 +1,14 @@
<?php
namespace Peidikeji\Goods;
use Dcat\Admin\Extend\ServiceProvider;
use Dcat\Admin\Admin;
class GoodsServiceProvider extends ServiceProvider
{
protected $menu = [
['title' => '商品管理', 'uri' => '', 'icon' => ''],
['title' => '商品分类', 'uri' => 'goods/category', 'icon' => '', 'parent' => '商品管理'],
];
}

View File

@ -0,0 +1,63 @@
<?php
namespace Peidikeji\Goods\Http\Controllers\Admin;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Http\Controllers\AdminController;
use Dcat\Admin\Show;
use Peidikeji\Goods\Models\GoodsCategory;
class GoodsCategoryController extends AdminController
{
protected $translation = 'peidikeji.dcat-admin-extension-goods::goods-category';
protected function grid()
{
$grid = Grid::make(new GoodsCategory());
$grid->disableRowSelector();
$grid->column('name')->tree(true, false);
$grid->column('image')->image('', 100);
$grid->column('sort')->editable(['mask' => '{alias:\'numeric\',min:0,max:999}']);
$grid->column('is_enable')->switch();
return $grid;
}
protected function form()
{
$form = Form::make(GoodsCategory::with(['parent']));
$form->select('parent_id')->help('不选默认为顶级')->options(GoodsCategory::selectOptions())->default(0);
$form->text('name')->required();
$form->image('image')
->uniqueName()
->move('article-category')
->autoUpload();
$form->number('sort')
->min(0)
->default(1)
->help('数值越小, 越靠前');
$form->switch('is_enable')->default(1);
$form->text('description');
return $form;
}
protected function detail($id)
{
$info = GoodsCategory::with(['parent'])->findOrFail($id);
$show = Show::make($info);
$show->field('name');
$show->field('parent.name');
$show->field('image')->image('', 100);
$show->field('description');
$show->field('sort');
return $show;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Peidikeji\Goods\Http\Controllers\Admin;
use Illuminate\Support\Facades\Route;
Route::resource('goods/category', GoodsCategoryController::class);

View File

@ -0,0 +1,15 @@
<?php
namespace Peidikeji\Goods\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Goods extends Model
{
use SoftDeletes;
protected $table = 'goods';
protected $fillable = ['attr', 'category_id', 'content', 'cover_image', 'deleted_at', 'description', 'goods_sn', 'images', 'name', 'on_sale', 'part', 'price', 'sold_count', 'spec', 'stock'];
}

View File

@ -0,0 +1,71 @@
<?php
namespace Peidikeji\Goods\Models;
use Dcat\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Model;
class GoodsCategory extends Model
{
use ModelTree;
protected $table = 'goods_category';
protected $fillable = ['name', 'image', 'description', 'parent_id', 'level', 'sort', 'path', 'is_enable'];
protected $titleColumn = 'name';
protected $orderColumn = 'sort';
public $timestamps = false;
protected static function boot()
{
parent::boot();
// 监听 Category 的创建事件,用于初始化 path 和 level 字段值
static::creating(function ($category) {
// 如果创建的是一个根类目
if (!$category->parent_id) {
// 将层级设为 1
$category->level = 1;
// 将 path 设为 -
$category->path = '-';
} else {
// 将层级设为父类目的层级 + 1
$category->level = $category->parent->level + 1;
// 将 path 值设为父类目的 path 追加父类目 ID 以及最后跟上一个 - 分隔符
$category->path = $category->parent->path.$category->parent_id.'-';
}
});
static::deleting(function ($category) {
// 所有下级分类
$ids = GoodsCategory::where('path', 'like', '%-'.$category->id.'-%')->pluck('id');
// 检查下级分类是否包含商品
if (Goods::whereIn('category_id', array_merge($ids, [$category->id]))->exists()) {
// todo 阻止删除该分类
}
// 删除所有下级分类
GoodsCategory::where('path', 'like', '%-'.$category->id.'-%')->delete();
});
}
public function parent()
{
return $this->belongsTo(self::class, 'parent_id');
}
public function children()
{
return $this->hasMany(self::class, 'parent_id');
}
public function goods()
{
return $this->hasMany(Goods::class, 'category_id');
}
public function scopeOrder($q)
{
return $q->orderBy('sort');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Peidikeji\Goods;
use Dcat\Admin\Extend\Setting as Form;
class Setting extends Form
{
public function form()
{
$this->text('key1')->required();
$this->text('key2')->required();
}
}

View File

@ -0,0 +1,81 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGoodsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
$this->down();
Schema::create('goods_category', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('分类名称');
$table->string('image')->nullable()->comment('封面图');
$table->string('description')->nullable()->comment('描述');
$table->unsignedBigInteger('parent_id')->default(0)->comment('父级ID');
$table->unsignedInteger('level')->default(1)->comment('层级');
$table->unsignedInteger('sort')->default(1)->comment('排序 asc');
$table->unsignedTinyInteger('is_enable')->default(1)->comment('状态');
$table->string('path')->default('-')->comment('所有的父级ID');
$table->comment('商品分类');
});
Schema::create('goods', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('category_id')->comment('所属分类, 关联 goods_category.id');
$table->string('name')->comment('商品名称');
$table->string('goods_sn')->unique()->comment('编号');
$table->string('cover_image')->nullable()->comment('封面图');
$table->json('images')->nullable()->comment('图片集');
$table->string('description')->nullable()->comment('描述');
$table->text('content')->nullable()->comment('详细');
$table->unsignedInteger('on_sale')->default(0)->comment('是否上架');
$table->unsignedInteger('stock')->default(0)->comment('库存');
$table->unsignedInteger('sold_count')->default(0)->comment('销量');
$table->decimal('price', 12, 2)->comment('售价');
$table->json('attr')->nullable()->comment('属性');
$table->json('spec')->nullable()->comment('规格');
$table->json('part')->nullable()->comment('配件');
$table->timestamps();
$table->softDeletes();
$table->foreign('category_id')->references('id')->on('goods_category');
$table->comment('商品');
});
Schema::create('goods_sku', function (Blueprint $table) {
$table->id();
$table->string('sn')->unique()->comment('货号');
$table->unsignedBigInteger('goods_id')->comment('所属商品, 关联 goods.id');
$table->string('name')->comment('名称');
$table->decimal('price', 12, 2)->comment('价格');
$table->unsignedInteger('stock')->comment('库存');
$table->json('spec')->nullable()->comment('规格');
$table->foreign('goods_id')->references('id')->on('goods');
$table->comment('商品-SKU');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('goods_sku');
Schema::dropIfExists('goods');
Schema::dropIfExists('goods_category');
}
};

View File

@ -0,0 +1,7 @@
<?php
return [
'1.0.0' => [
'CreateGoodsTable.php',
],
];

View File

@ -0,0 +1,56 @@
<?php
use Dcat\Admin\Models\Permission;
use Illuminate\Database\Seeder;
class KeywordsTableSeeder extends Seeder
{
public function run()
{
// 添加权限
$permissions = [
'keywords' => ['name' => '字典管理', 'curd' => true]
];
// Permission::where('slug', 'like', 'dcat.admin.keywords%')->delete();
$this->createPermissionData($permissions);
}
protected function createPermissionData(array $permissions, string $key = '', int $pId = 0)
{
$curdArr = [
'index' => '列表',
'create' => '新增',
'edit' => '修改',
'destroy' => '删除',
'show' => '详情',
];
foreach ($permissions as $slug => $permission) {
//是否已存在该权限
$slugKey = 'dcat.admin.' . ($key ? $key . '.' . $slug : $slug);
$pper = Permission::updateOrCreate(['slug' => $slugKey], ['name' => is_string($permission) ? $permission : $permission['name'], 'parent_id' => $pId]);
if (!is_string($permission)) {
if (!isset($permission['children'])) {
$permission['children'] = [];
}
//判断是否默认插入curd权限
if (isset($permission['curd']) && $permission['curd']) {
if (is_array($permission['curd'])) {
$permission['curd'] = array_reverse($permission['curd']);
foreach ($permission['curd'] as $value) {
$permission['children'] = array_merge([$value => $curdArr[$value]], $permission['children']);
}
} else {
$permission['children'] = array_merge($curdArr, $permission['children']);
}
}
if (count($permission['children']) > 0) {
$_key = $permission['curd'] !== false ? ($key ? $key . '.' . $slug : $slug) : $key;
$this->createPermissionData($permission['children'], $_key ?? $slug, $pper->id);
}
}
}
}
}

View File

@ -2,6 +2,7 @@
return [
'1.0.0' => [
'CreateKeywordsTable.php'
'CreateKeywordsTable.php',
'KeywordsTableSeeder.php'
],
];

View File

@ -134,7 +134,7 @@ class Field implements Renderable
*
* @var array
*/
protected $attributes = [];
protected $attributes = ['autocomplete' => 'off'];
/**
* Parent form.

View File

@ -251,7 +251,7 @@ class Tools implements Renderable
return <<<HTML
<div class="btn-group pull-right btn-mini" style="margin-right: 5px">
<a href="{$this->getListPath()}" class="btn btn-sm btn-primary ">
<a href="javascript:window.history.back()" class="btn btn-sm btn-primary ">
<i class="feather icon-list"></i><span class="d-none d-sm-inline"> {$list}</span>
</a>
</div>