HPlus Admin,全新admin插件 快速开发框架,
Admin插件使用体验和laravel-admin用法差不多
auth组件采用hyperf-auth,目前支持 jwt、session 驱动。用户可以自行扩展。使用体验大体和 laravel 的 auth 差不多
灵活可替换的权限验证组件,HPlus提供权限验证,也可以替换自己的权限验证插件
演示地址:
demo.hyperf.plus/auth#/auth/…
账户 admin
密码 admin
欢迎加入HPlus交流群,群聊号码:512465490
点击链接加入群聊【hyperf-admin交流群】:群聊号码:512465490
laravel版本地址 laravel-vue-admin
以插件形式开箱即用
可以做到无需VUE前端可实现快速开发各种表单
安装
服务器要求
Hyperf 对系统环境有一些要求,仅可运行于 Linux 和 Mac 环境下,但由于 Docker 虚拟化技术的发展,在 Windows 下也可以通过 Docker for Windows 来作为运行环境,通常来说 Mac 环境下,我们更推荐本地环境部署,以避免 Docker 共享磁盘缓慢导致 Hyperf 启动速度慢的问题。
hyperf\hyperf-docker 项目内已经为您准备好了各种版本的 Dockerfile ,或直接基于已经构建好的 hyperf\hyperf 镜像来运行。
当您不想采用 Docker 来作为运行的环境基础时,您需要确保您的运行环境达到了以下的要求:
PHP >= 7.2
Swoole PHP 扩展 >= 4.5,并关闭了 Short Name
OpenSSL PHP 扩展
JSON PHP 扩展
PDO PHP 扩展 (如需要使用到 MySQL 客户端)
Redis PHP 扩展 (如需要使用到 Redis 客户端)
Protobuf PHP 扩展 (如需要使用到 gRPC 服务端或客户端)
- 更多请参考hyperf官方 安装要求和Docker安装方式
全新安装
- 创建hyperf应用
composer create-project hyperf/hyperf-skeleton
- 创建完毕后配置数据库
- 按照下方
已有项目安装方式进行安装
已有项目安装
- 1、安装Admin插件
Hyperf2.0版本
composer require hyperf-plus/admin:~2.1
Hyperf2.1版本
composer require hyperf-plus/admin:~2.2
- 2、生成admin auth file配置文件
php bin/hyperf.php vendor:publish hyperf-plus/admin
- 3、UI资源初始化(建议有修改vue需求的用户,可以查看UI文档,以插件形式开发,尽量不要修改默认的样式,这样后期UI插件有新功能更新也能实现无痛更新)
php bin/hyperf.php ui:init
- 4、配置好数据库(必须),然后执行下面安装命令
php bin/hyperf.php admin:install
- 5、配置异常处理器,可以自行拦截处理,也可以按照以下方式添加异常处理器
在文件 config/autoload/exceptions.php 中添加 \HPlus\Admin\Exception\Handler\AppExceptionHandler::class 异常处理器
<?php
return [
'handler' => [
'http' => [
\HPlus\Admin\Exception\Handler\AppExceptionHandler::class, #放到第一位
# 其他的放到下面
],
],
];
- 6、(可选)添加权限控制插件(如果不启用默认权限控制,可以忽略此步骤)
composer require hyperf-plus/permission
默认没有安装权限插件,需要手动安装,此为了更好的扩展,可以自行配置项目已有的权限模块
可在将admin.php 配置文件中权限验证中间件,这样通过注解AdminController注册的路由都会默认加上配置的此中间件 示例代码如下
<?php
return [
#...省略
'route' => [
#...省略
'middleware' => [AuthMiddleware::class,自己的权限验证中间件],
],
#...省略
]
需要验证权限的地方用AdminController注解路由来定义,或者添加中间件PermissionMiddleware即可
此插件支持注解路由插件 hyperf-plus-route插件的注解参数
如:控制器注解:ApiController
方法注解:GetApi PostApi PutApi DeleteApi (方法上配置级别优先于控制器配置)
1、userOpen 对用户开放url中的验证,
2、security 为true必须验证权限 false公共开放资源
路由注解只在启动第一次时扫描并缓存,后续请求不会再做解析,提高性能
- 7、(可选)日志记录,添加日志管理中间件,日志记录功能数据量较大,默认不开启(如需开启在admin配置文件的route节点下middleware添加LogsMiddleware中间件即可 ) 或者在需要加日志的接口,注解上LogsMiddleware中间件即可记录
<?php
return [
#...省略
'route' => [
#...省略
'middleware' => [AuthMiddleware::class, LogsMiddleware::class, 其他中间件],
],
#...省略
]
- 8、启动服务
php bin/hyperf.php start
访问 http://127.0.0.1:9501/auth
- 账户 admin
- 密码 admin
组件
展示组件
Card 卡片
将信息聚合在卡片容器中展示。
$header = '标题 <a style="float:right;">测试</a>'; //html文本
$content = new Content; // 对象
$header = $content->row(function (Row $row) {
$row->column(12, Widgets\Text::make('标题'));
$row->column(12, Form\CSwitch::make()->style(['float' => 'right']));
});
Card::make()->header(function (Content $content)
{
$content->className('mt-10')->body('测试内容'); // 闭包
})->content();
// content同理
Steps 步骤条
引导用户按照流程完成任务的分步导航条,可根据实际应用场景设定步骤,步骤不得少于 2 步。

Steps::make()
->simple(false)
->active($order->orderStep())
->processStatus("process")
->alignCenter(true)
->stepList(function (Collection $list) use ($order) {
//下单
$xd = Step::make()->title("下单");
$xd->description($order->created_at);
$list->push($xd);
//付款
$fk = Step::make()->title("付款");
$fk->description($order->pay_time);
$list->push($fk);
//发货
$fh = Step::make()->title("发货");
$fh->description($order->delivery_time);
$list->push($fh);
//收货
$sh = Step::make()->title("收货");
$sh->description($order->receipt_time);
$list->push($sh);
//完成
$wc = Step::make()->title("完成");
$wc->description($order->receipt_time);
$list->push($wc);
}));
HTML
组件使用v-html渲染
Html::make()->html("<div>......</div>");
Text
组件使用v-bind渲染
Text::make()->html("我是纯文本");
Alert警告
用于页面中展示重要的提示信息。
Alert::make("title","desc");
属性请查看 element.eleme.cn/#/zh-CN/com…
表格组件
Tag 标签
更多属性请查看element-ui文档
Tag::make();
type
默认,会从 success/info/warning/danger 随机显示一个
Tag::make()->type();
指定值
Tag::make()->type('info');
指定随机组
Tag::make()->type(['info','danger']);
指定值对应
Tag::make()->type(['yes'=>'info','on'=>'danger',1=>'success',0=>'warning']);
是否可关闭
Tag::make()->closable();
是否禁用渐变动画
Tag::make()->disableTransitions();
是否有边框描边
Tag::make()->hit();
尺寸
medium / small / mini
Tag::make()->size('mini');
主题
dark / light / plain
Tag::make()->effect('dark');
Link 文字链接
Link::make();
type设置
默认,会从 primary / success / warning / danger / info 随机显示一个
Tag::make()->type();
//指定值
Tag::make()->type('info');
//指定随机组
Tag::make()->type(['info','danger']);
//指定值对应
Tag::make()->type(['yes'=>'info','on'=>'danger',1=>'success',0=>'warning']);
是否下划线
Tag::make()->underline();
是否禁用状态
Tag::make()->disabled();
原生 href 属性
Tag::make()->href("http://www.baidu.com");
图标类名
可直接使用内置 Icon 图标,或使用自定义图标 更多属性请查看element-ui文档
Tag::make()->icon('el-icon-platform-eleme');
//OR
Tag::make()->icon('iconfont my-icon-name');
Avatar 头像
属性与 Element Avatar相同
Avatar::make();
Image 图片
可显示单张或多张图片,支持大图预览,更多属性请查看element-ui文档
Image::make();
Icon 图标
更多属性请查看element-ui文档
Icon::make()
动态 Dialog 对话框(推荐使用)
目前此组件不能单独使用,需配合其他组件使用,如Button,BatchAction,ActionButton,ToolbarButton

例如在grid栏位中,使用 如果设置url,则弹窗的布局是先请求这个url,获取到布局json并渲染到弹窗上,如果没有设置url则以slot设置的布局为准
url中可选增加动态参数 如下所示 在url中增加{id} 则实际请求中会替换成该行id的值,生成弹窗布局
$grid->toolbars(function (Grid\Toolbars $toolbars) {
$toolbars->addRight(Grid\Tools\ToolButton::make('工具栏动态弹窗')->dialog(function (Dialog $dialog) {
$dialog->setUrl('/admin/test/testhhah');
$dialog->title('工具栏动态弹窗');
}));
});
$grid->batchActions(function (Grid\BatchActions $action) {
$action->add(Grid\BatchActions\BatchAction::make('批量选择后动态弹窗')->dialog(function (Dialog $dialog) {
$dialog->setUrl('/admin/test/testhhah?name=selectionKeys');
$dialog->title('批量选择后动态弹窗');
}));
});
$grid->column('username', '用户名')->component(
Button::make('查看更多')->type('text')->dialog(function (Dialog $dialog) {
$dialog->setUrl('/admin/test/testhhah?name={id}');
$dialog->title('栏位中弹窗');
})
);
$grid->actions(function (Grid\Actions $actions) {
$actions->add(Grid\Actions\ActionButton::make('查看')->dialog(function (Dialog $dialog) use ($actions) {
$id = $actions->getRow()->id; #这里是当前行的ID
$dialog->title('查看');
$dialog->setUrl('/admin/test/testhhah?id={id}');
}));
});
例如在form中,使用

url中可选增加动态参数 如下所示 在url中增加{key} 则实际请求中会替换成表单中该字段的值
$form->item('edit', 'hh')->component(Button::make('点击弹窗')->dialog(function (Dialog $dialog) {
$dialog->setUrl('/admin/test/test?id={key}');
$dialog->title('查看弹窗');
}));
Dialog 对话框 (旧版本)
目前此组件不能单独使用,需配合其他组件使用,如ActionButton,ToolbarButton
Dialog::make()
->.....//更多属性请查看element-ui文档
->slot(function(Content $content){//弹窗内容组件,闭包传入一个content组件
});
操作组件
ActionButton
可用于vue路由导航,异步请求,连接跳转,dialog 操作
ActionButton::make("ActionName")
->order(3) //排序 越大越靠前
->icon("icon-class-name")//图标
->message("确认操作提示信息")
->tooltip("气泡提示")//无message时生效
->handler("route")
->uri("WeChat/manage/{app_id}")//路径,{xxx}会被自动替换成当前行的对应值,支持 ?x=x 参数
->dialog(function($dialog){//返回dialog实例
})
//调用代码
$grid->actions(function (Grid\Actions $actions) {
$actions->add(...);
});
Dialog代码示例

$actions->add(ActionButton::make("发货")->order(4)->dialog(function (Dialog $dialog) use ($actions) {
$dialog->title("订单发货")->showClose(false)->width('500px');
$dialog->slot(function (Content $content) use ($actions) {
$form = new Form();
$form->action(route('order/deliver'));
$form->isGetData(false);
$row = $actions->getRow();
$real_name = $row->address->real_name;
$phone = $row->address->phone ?? '';
$address = ($row->address->province ?? '') . ($row->address->city ?? '') . ($row->address->district ?? '') . ($row->address->detail ?? '');
$form->item('id', '订单ID', 'id')->defaultValue($row->id)->component(Input::make()->readonly());
$form->item('real_name', '收货人')->defaultValue($real_name)->component(Input::make()->readonly());
$form->item('phone', '电话')->defaultValue($phone)->component(Input::make()->readonly());
$form->item('province', '地址')->defaultValue($address)->component(Input::make()->readonly());
$form->item("express_company", "物流公司")->defaultValue($row->express_company)->required();
$form->item("express_no", "物流单号")->defaultValue($row->express_no)->required();
# 用这个是关闭弹窗
# 关闭弹窗、并刷新表格 绑定到父表单ref为photo
$form->successRefData('photo', function () {
return <<<JS
ref.\$bus.emit("tableReload");
ref.\$bus.emit("closeDialog");
JS;
});
$form->actions(function (FormActions $form) {
$form->hideCancelButton();
$form->submitButton()->content('发货');
return $form;
});
$content->row($form);
});
}));
这里的dialog展示的是一个表单,当然你可以展示任意组件
批量操作组件
BatchAction
可用于vue路由导航,异步请求,连接跳转 , Dialog
BatchAction::make("加入活动")
->uri('...')//批量操作路径
->handler(BatchAction::HANDLER_REQUEST)//批量操作响应事件类型
->route('...')//vue路由快捷设置方法
->requestMethod('post')//设置request模式请求类型
->message('...')//确认操作提示信息
->beforeEmit('name','data')//请求前出发事件
->successEmit('name','data')//操作成功后触发事件
->afterEmit('name','data')//操作完成后触发事件,失败成功都会触发
->dialog(Dialog)//设置dialog弹窗
工具栏组件
ToolButton
可用于vue路由导航,异步请求,连接跳转 , Dialog 普通演示
Grid\Tools\ToolButton::make("同步粉丝")
->handler("request") // 类型 request|route|link
->message("确认操作提示信息")
->tooltip("气泡提示")
->uri("") //路径
Dialog演示,Dialog属性请参考
$toolbars->addRight(Grid\Tools\ToolButton::make("采集")->dialog(function (Dialog $dialog){
$dialog->slot(function (Content $content) {
$content->row(Alert::make("123456"));
});
}));
其他属性可参考 el-button
表单组件
基于element-ui的表单组件实现,基本上所有的组件功能都实现了。使用过程中可查看element-ui的文档,调用的时候make()->即可
IconChoose 图标选择器
IconChoose::make()
Radio 单选框
更多属性请查看element-ui文档
RadioGroup::make(1, [
Radio::make(1, "公众号"),
Radio::make(2, "小程序"),
])
Checkbox 多选框
更多属性请查看element-ui文档
CheckboxGroup::make()->options([
Checkbox::make(value,name),
Checkbox::make(value,name),
]);
Input 输入框
更多属性请查看element-ui文档
Input::make()
InputNumber 计数器
更多属性请查看element-ui文档
InputNumber::make()
Select 选择器
Select::make()
->filterable()
->options(function () {
return [
SelectOption::make(id, name)->avatar("")->desc("")
];
})
支持远程搜索
Select::make()->filterable()->remote($remoteUrl)
Select::make()->filterable()->remote($remoteUrl)->extUrlParams(['type'=>'A']) // 远程搜索带参数
Select::make()->filterable()->remote($remoteUrl)->depend(['keyA','keyB.0.key']) // 远程搜索带表单值
// 带分页加载的数据反馈接受
// {data:{data:[],total:x}} // 优先接受此框架一般返回 或
// {data:[],meta:{total:x}} // laravel资源返回
Select::make()->filterable()->remote($remoteUrl)->paginate($per_page = 10) // 远程搜索带分页加载
// 远程搜索占位显示
$label = [
'key'=>'model', // 模型中支持的方法
'value' =>
[
'value'=>'id', //同样支持复合键位
'label'=>['title','label']
]
]
//注意 $form 一般通过use 传递
Select::make()->filterable()->remote($remoteUrl)->label($form, $label)
支持 更多属性请查看element-ui文档
Cascader 级联选择器
当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择 基础用法 模型导入
ModelTree
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
use SmallRuralDog\Admin\Traits\ModelTree;
class GoodsClass extends Model
{
use ModelTree;
public function children()
{
return $this->hasMany(get_class($this), 'parent_id')->orderBy('order');
}
}
使用demo
goods_class_path 需要设置成json类型
protected $casts = [
"goods_class_path" => "json"
];
$form->item("goods_class_path", "产品分类")->displayComponent(function () {
$goods_class = new GoodsClass();
$allNodes = $goods_class->toTree();
return Cascader::make()->options($allNodes)->value("id")->label("name")->expandTrigger("hover");
}),
属性 显示为面板模式
Cascader::make()->panel(true)
更多属性请查看element-ui文档
Switch 开关
CSwitch::make()
更多属性请查看element-ui文档
Slider 滑块
Slider::make()
更多属性请查看element-ui文档
TimePicker 时间选择器
TimePicker::make()
更多属性请查看element-ui文档
DatePicker 日期选择器
DatePicker::make()
更多属性请查看element-ui文档
DateTimePicker 日期时间选择器
DateTimePicker::make()
更多属性请查看element-ui文档
Upload 上传
通过以下的调用来生成上传组件
$form->item('avatar', '头像')->displayComponent(Upload::make()->pictureCard()->avatar()->path('avatar')->uniqueName())
//or
$form->item('avatar', '头像')->displayComponent(function(){
return Upload::make()->pictureCard()->avatar()->path('avatar')->uniqueName();
})
上传地址 自定义上传地址
Upload::make()->action("http://xxxx")
文件URL前缀 如果数据库保存的是相对地址,则这个就是它的URL前面部分。默认为disk的路径
Upload::make()->host("http://xxxx")
支持多文件 支持多个文件上传,数据格式为数组
Upload::make()->multiple();
//如果是一对多情况下,并且是对象数组,需要指定文件组件,文件路径字段
Upload::make()->multiple(true,"keyName","valueName");
上传附加数据
Upload::make()->data(['key'=>'value','key_2'=>'value'])
保存目录
Upload::make()->path("path_name")
自动生成文件名 默认为上传的文件名
Upload::make()->uniqueName()
拖拽上传
Upload::make()->drag()
文件类型 接受上传的文件类型
Upload::make()->accept("xx")
文件个数 默认为一个
Upload::make()->limit(10)
禁用
Upload::make()->disabled()
组件类型 支持 image avatar file
Upload::make()->image()
Upload::make()->avatar()
Upload::make()->file()
组件大小 组件item的高宽,默认 100x100
Upload::make()->width(150)
Upload::make()->height(120)
Rate 评分
Rate::make()
ColorPicker 颜色选择器
ColorPicker::make()
Transfer 穿梭框
Transfer::make()->data($permissionModel::get()->map(function ($item) {
return TransferData::make($item->id, $item->name);
}))->titles(['可授权', '已授权'])->filterable()
WangEditor
轻量级 web 富文本编辑器
WangEditor::make()
->menus([])
->zIndex(999)
->uploadImgShowBase64(true)
->uploadImgServer("")
->uploadFileName("file")
->uploadImgHeaders(['xx'=>'xx'])
->style("height:600px;")//设置高度
->component(Html::make()->html("123456789"));//添加工具栏与编辑区域中间的自定义组件
自定义组件有两个props
-
attrs:当前组件属性对象 -
editor:当前编辑器对象,可以使用this.editor调用各种方法
统计图表
g2plot 是一套简单、易用、并具备一定扩展能力和组合能力的统计图表库,基于图形语法理论搭建而成,"g2plot"中的 g2 即意指图形语法 (the Gramma of Graphics),同时也致敬了 ggplot2。

Line - 折线图
使用一条折线的线段显示数据在一个具有顺序性的维度上的变化。
Line::make()
->data(function () {
$data = collect();
for ($year = 2010; $year <= 2020; $year++) {
$data->push([
'year' => (string)$year,
'type'=>'type1',
'value' => rand(100, 1000)
]);
$data->push([
'year' => (string)$year,
'type'=>'type2',
'value' => rand(100, 1000)
]);
}
return $data;
})
->config(function () {
return [
'title' => [
'visible' => true,
'text' => '折线图',
],
'seriesField'=>'type',
'smooth'=>true,
'xField' => 'year',
'yField' => 'value'
];
});
具体请参考:g2plot.antv.vision/zh/examples…
StepLine - 阶梯折图
阶梯线图用于表示连续时间跨度内的数据,它通常用于显示某变量随时间的变化模式:是上升还是下降,是否存在周期性的循环?因此,相对于独立的数据点,折线图关注的是全局趋势。
StepLine::make()->data()->config();
具体参数请参考:g2plot.antv.vision/zh/examples…
Area - 面积图
面积图又叫区域图。 它是在折线图的基础之上形成的,它将折线图中折线与自变量坐标轴之间的区域使用颜色或者纹理填充,这样一个填充区域我们叫做面积,颜色的填充可以更好的突出趋势信息。
面积图用于强调数量随时间而变化的程度,也可用于引起人们对总值趋势的注意。他们最常用于表现趋势和关系,而不是传达特定的值。
Area::make()->data()->config();
具体参数请参考:g2plot.antv.vision/zh/examples…
Column - 柱状图
柱状图用于描述分类数据之间的对比,如果我们把时间周期,如周、月、年,也理解为一种分类数据 (time category),那么柱状图也可以用于描述时间周期之间的数值比较。

Column::make()->data()->config();
具体参数请参考:g2plot.antv.vision/zh/examples…