界面代码

<?php

namespace App\Admin\Controllers\Demo;

use App\Admin\Extensions\Tools\UserGender;
use App\Http\Controllers\Controller;
use App\Models\ChinaArea;
use App\Models\User;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Controllers\ModelForm;
use Encore\Admin\Layout\Content;
use Encore\Admin\Widgets\Box;
use Encore\Admin\Widgets\Tab;
use Encore\Admin\Widgets\Table;
use Illuminate\Support\Facades\Request;

class UserController extends Controller
{
    use ModelForm;
    ...

    protected function grid()
    {
        return Admin::grid(User::class, function (Grid $grid) {

            $grid->model()->gender(Request::get('gender'));

            $grid->id('ID')->sortable();

            $grid->name()->editable();

            $grid->column('expand')->expand(function () {

                $profile = (array) $this->profile;

                $profile = array_only($profile, ['homepage', 'gender', 'birthday', 'address', 'last_login_at', 'last_login_ip', 'lat', 'lng']);

                return new Table([], $profile);

            }, 'Profile');

            $grid->column('position')->openMap(function () {

                return [$this->profile['lat'], $this->profile['lng']];

            }, 'Position');

            $grid->column('profile.homepage')->urlWrapper();

            $grid->email()->prependIcon('envelope');

            $grid->profile()->mobile()->prependIcon('phone');

            $grid->column('profile.age')->progressBar(['success', 'striped'], 'xs')->sortable();

            $grid->created_at();

            $grid->updated_at();

            $grid->filter(function ($filter) {
                $filter->useModal();
                $filter->like('name');
                $filter->like('email');

                $filter->equal('address.province_id', 'Province')
                    ->select(ChinaArea::province()->pluck('name', 'id'))
                    ->load('address.city_id', '/admin/api/china-area/city');

                $filter->equal('address.city_id', 'City')
                    ->select(function ($id) {
                        return ChinaArea::options($id);
                    })->load('address.district_id', '/admin/api/china-area/district');

                $filter->equal('address.district_id', 'District')
                    ->select(function ($id) {
                        return ChinaArea::options($id);
                    });
            });

            $grid->tools(function ($tools) {
                //$tools->append(new RefreshTimer(5000));
                $tools->append(new UserGender());
                //$tools->append(new ButtonGroup());
            });

            $grid->actions(function ($actions) {

                if ($actions->getKey() % 2 == 0) {
                    $actions->disableDelete();
                    $actions->append('<a href=""><i class="fa fa-eye"></i></a>');
                } else {
                    $actions->disableEdit();
                    $actions->prepend('<a href=""><i class="fa fa-paper-plane"></i></a>');
                }
            });

            $grid->disableBatchDeletion();
        });
    }

    public function form()
    {
        return User::form(function (Form $form) {

            $form->model()->makeVisible('password');

            $form->tab('Basic', function (Form $form) {

                $form->display('id');
                $form->text('name')->rules('required');
                $form->email('email')->rules('required');
                $form->display('created_at');
                $form->display('updated_at');

            })->tab('Profile', function (Form $form) {

                $form->url('profile.homepage');
                $form->ip('profile.last_login_ip');
                $form->datetime('profile.last_login_at');
                $form->color('profile.color')->default('#c48c20');
                $form->mobile('profile.mobile')->default(13524120142);
                $form->date('profile.birthday');

//                $form->map('profile.lat', 'profile.lng', 'Position')->useTencentMap();
                $form->slider('profile.age', 'Age')->options(['max' => 50, 'min' => 20, 'step' => 1, 'postfix' => 'years old']);
                $form->datetimeRange('profile.created_at', 'profile.updated_at', 'Time line');

            })->tab('Sns info', function (Form $form) {

                $form->text('sns.qq');
                $form->text('sns.wechat');
                $form->text('sns.weibo');
                $form->text('sns.github');
                $form->text('sns.google');
                $form->text('sns.facebook');
                $form->text('sns.twitter');
                $form->display('sns.created_at');
                $form->display('sns.updated_at');

            })->tab('Address', function (Form $form) {

                $form->select('address.province_id')->options(
                    ChinaArea::province()->pluck('name', 'id')
                )->load('address.city_id', '/admin/api/china-area/city');

                $form->select('address.city_id')->options(function ($id) {
                    return ChinaArea::options($id);
                })->load('address.district_id', '/admin/api/china-area/district');

                $form->select('address.district_id')->options(function ($id) {
                    return ChinaArea::options($id);
                });

                $form->text('address.address');

            })->tab('Password', function (Form $form) {

                $form->password('password')->rules('confirmed');
                $form->password('password_confirmation');

            });

            $form->ignore(['password_confirmation']);
        });

    ...
}

模型

app/Models/User.php

<?php

namespace App\Models;

use Encore\Admin\Traits\AdminBuilder;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    use AdminBuilder;

    protected $table = 'demo_users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function profile()
    {
        return $this->hasOne(UserProfile::class);
    }

    public function sns()
    {
        return $this->hasOne(UserSns::class);
    }

    public function address()
    {
        return $this->hasOne(UserAddress::class);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function friends()
    {
        return $this->belongsToMany(User::class, 'friends', 'user_id', 'friend_id');
    }

    /**
     *
     *
     * @param $query
     * @param $gender
     * @return mixed
     */
    public function scopeGender($query, $gender)
    {
        if (!in_array($gender, ['m', 'f'])) {
            return $query;
        }

        return $query->whereHas('profile', function ($query) use ($gender) {
            $query->where('gender',  $gender);
        });
    }
}

app/Models/UserProfile.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class UserProfile extends Model
{
    protected $table = 'demo_user_profiles';

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

app/Models/UserSns.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class UserSns extends Model
{
    protected $table = 'demo_user_sns';

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

app/Models/UserAddress.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class UserAddress extends Model
{
    protected $table = 'demo_user_address';

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

表结构

CREATE TABLE `demo_users` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `avatar` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
 `password` varchar(60) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `demo_user_profiles` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) NOT NULL,
 `homepage` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `mobile` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `avatar` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `document` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `gender` enum('m','f') COLLATE utf8_unicode_ci DEFAULT NULL,
 `birthday` date DEFAULT NULL,
 `address` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `color` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
 `age` tinyint(4) DEFAULT NULL,
 `last_login_at` timestamp NULL DEFAULT NULL,
 `last_login_ip` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `lat` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `lng` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `demo_user_sns` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `qq` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `wechat` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `weibo` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `github` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `google` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `facebook` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `twitter` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `demo_user_address` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` int(11) unsigned NOT NULL,
 `province_id` int(11) unsigned DEFAULT '0',
 `city_id` int(11) unsigned DEFAULT '0',
 `district_id` int(11) unsigned DEFAULT '0',
 `address` varchar(255) COLLATE utf8_unicode_ci DEFAULT '',
 `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`),
 KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

扩展

Add following code in `app/Admin/bootstrap.php`:

use App\Admin\Extensions\Column\ExpandRow;
use App\Admin\Extensions\Column\OpenMap;
use App\Admin\Extensions\Column\FloatBar;
use App\Admin\Extensions\Column\UrlWrapper;
use Encore\Admin\Grid\Column;

Admin::js('/packages/clipboard/dist/clipboard.min.js');

Column::extend('expand', ExpandRow::class);
Column::extend('openMap', OpenMap::class);
Column::extend('floatBar', FloatBar::class);
Column::extend('urlwrapper', UrlWrapper::class);

Column::extend('prependIcon', function ($value, $icon) {

    return "<span style='color: #999;'><i class='fa fa-$icon'></i>  $value</span>";

});

Admin/Extensions/Column/ExpandRow.php

<?php

namespace App\Admin\Extensions\Column;

use Encore\Admin\Admin;
use Encore\Admin\Grid\Displayers\AbstractDisplayer;

class ExpandRow extends AbstractDisplayer
{
    public function display(\Closure $callback = null, $btn = '')
    {
        $callback = $callback->bindTo($this->row);

        $html = call_user_func($callback);

        $script = <<<EOT

$('.grid-expand').on('click', function () {
    if ($(this).data('inserted') == '0') {
        var key = $(this).data('key');
        var row = $(this).closest('tr');
        var html = $('template.grid-expand-'+key).html();

        row.after("<tr><td colspan='"+row.find('td').length+"' style='padding:0 !important; border:0px;'>"+html+"</td></tr>");

        $(this).data('inserted', 1);
    }

    $("i", this).toggleClass("fa-caret-right fa-caret-down");
});
EOT;
        Admin::script($script);

        $btn = $btn ?: $this->column->getName();

        $key = $this->getKey();

        return <<<EOT
<a class="btn btn-xs btn-default grid-expand" data-inserted="0" data-key="{$key}" data-toggle="collapse" data-target="#grid-collapse-{$key}">
    <i class="fa fa-caret-right"></i> $btn
</a>
<template class="grid-expand-{$key}">
    <div id="grid-collapse-{$key}" class="collapse">$html</div>
</template>
EOT;
    }
}

Admin/Extensions/Column/OpenMap.php

<?php

namespace App\Admin\Extensions\Column;

use Encore\Admin\Admin;
use Encore\Admin\Grid\Displayers\AbstractDisplayer;

class OpenMap extends AbstractDisplayer
{
    public function display(\Closure $callback = null, $btn = '')
    {
        $callback = $callback->bindTo($this->row);

        list($latitude, $longitude) = call_user_func($callback);

        $key = $this->getKey();

        $name = $this->column->getName();

        Admin::script($this->script());

        return <<<EOT
<button class="btn btn-xs btn-default grid-open-map" data-key="{$key}" data-lat="$latitude" data-lng="$longitude" data-toggle="modal" data-target="#grid-modal-{$name}-{$key}">
    <i class="fa fa-map-marker"></i> $btn
</button>

<div class="modal" id="grid-modal-{$name}-{$key}" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span></button>
        <h4 class="modal-title">$btn</h4>
      </div>
      <div class="modal-body">
        <div id="grid-map-$key" style="height:450px;"></div>
      </div>
    </div>
    <!-- /.modal-content -->
  </div>
  <!-- /.modal-dialog -->
</div>
EOT;
    }

    protected function script()
    {
        return <<<EOT

$('.grid-open-map').on('click', function() {

    var key = $(this).data('key');
    var lat = $(this).data('lat');
    var lng = $(this).data('lng');

    var center = new qq.maps.LatLng(lat, lng);

    var container = document.getElementById("grid-map-"+key);
    var map = new qq.maps.Map(container, {
        center: center,
        zoom: 13
    });

    var marker = new qq.maps.Marker({
        position: center,
        draggable: true,
        map: map
    });
});

EOT;
    }
}

Admin/Extensions/Column/FloatBar.php

<?php

namespace App\Admin\Extensions\Column;

use Encore\Admin\Admin;
use Encore\Admin\Grid\Displayers\AbstractDisplayer;

class FloatBar extends AbstractDisplayer
{
    protected function script()
    {
        return <<<EOT

$('.grid-float-bar').closest('tr').mouseover(function () {
    $(this).find('.grid-float-bar').removeClass('hide');
});

$('.grid-float-bar').closest('tr').mouseout(function () {
    $(this).find('.grid-float-bar').addClass('hide');
});

EOT;

    }

    public function display()
    {
        Admin::script($this->script());

        return <<<EOT
<div style="width:220px;">
    <div class="hide grid-float-bar">
        <a class="btn btn-xs btn-default"><i class="fa fa-thumbs-up"></i> Up</a>
        <a class="btn btn-xs btn-default"><i class="fa fa-thumbs-down"></i> Down</a>
        <a class="btn btn-xs btn-default"><i class="fa fa-heart"></i> Like</a>
        <a class="btn btn-xs btn-default"><i class="fa fa-share"></i> Share</a>
    </div>
</div>
EOT;
    }
}

Admin/Extensions/Column/UrlWrapper.php

<?php

namespace App\Admin\Extensions\Column;

use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid\Displayers\AbstractDisplayer;

class UrlWrapper extends AbstractDisplayer
{
    protected function script()
    {
        return <<<EOT

$('.grid-qrcode').popover({
    title: "Scan code to visit",
    html: true,
    trigger: 'focus'
});

new Clipboard('.clipboard');

$('.clipboard').tooltip({
  trigger: 'click',
  placement: 'bottom'
}).mouseout(function (e) {
    $(this).tooltip('hide');
});

EOT;

    }

    public function display()
    {
        Admin::script($this->script());

        $qrcode = "<img src='https://api.qrserver.com/v1/create-qr-code/?size=150x150&data={$this->value}' style='height: 150px;width: 150px;'/>";

        return <<<EOT

<div class="input-group" style="width:250px;">
  <input type="text" id="grid-homepage-{$this->getKey()}" class="form-control input-sm" value="{$this->value}" />
  <span class="input-group-btn">
    <button class="btn btn-default btn-sm clipboard" data-clipboard-target="#grid-homepage-{$this->getKey()}" title="Copied!">
        <i class="fa fa-clipboard"></i>
    </button>
    <a class="btn btn-default btn-sm grid-qrcode" data-content="$qrcode" data-toggle='popover' tabindex='0'>
        <i class="fa fa-qrcode"></i>
    </a>
  </span>
</div>

EOT;

    }
}

app/Admin/Extensions/Tools/UserGender.php

<?php

namespace App\Admin\Extensions\Tools;

use Encore\Admin\Admin;
use Encore\Admin\Grid\Tools\AbstractTool;
use Illuminate\Support\Facades\Request;

class UserGender extends AbstractTool
{
    public function script()
    {
        $url = Request::fullUrlWithQuery(['gender' => '_gender_']);

        return <<<EOT

$('input:radio.user-gender').change(function () {

    var url = "$url".replace('_gender_', $(this).val());

    $.pjax({container:'#pjax-container', url: url });

});

EOT;
    }

    public function render()
    {
        Admin::script($this->script());

        $options = [
            'all'   => 'All',
            'm'     => 'Male',
            'f'     => 'Female',
        ];

        return view('admin.tools.gender', compact('options'));
    }
}

resources/views/admin/tools/gender.blade.php

<div class="btn-group" data-toggle="buttons">
    @foreach($options as $option => $label)
    <label class="btn btn-default btn-sm {{ \Request::get('gender', 'all') == $option ? 'active' : '' }}">
        <input type="radio" class="user-gender" value="{{ $option }}">{{$label}}
    </label>
    @endforeach
</div>

-END-

results matching ""

    No results matching ""