Prechádzať zdrojové kódy

feat: views 复制出来放到外面

igb 5 mesiacov pred
rodič
commit
dd8c93d385
100 zmenil súbory, kde vykonal 5062 pridanie a 0 odobranie
  1. 43 0
      resources/views/distributor/dashboard/author.blade.php
  2. 15 0
      resources/views/distributor/dashboard/dependencies.blade.php
  3. 11 0
      resources/views/distributor/dashboard/environment.blade.php
  4. 52 0
      resources/views/distributor/dashboard/extensions.blade.php
  5. 43 0
      resources/views/distributor/dashboard/title.blade.php
  6. 27 0
      resources/views/distributor/filter/between-datetime.blade.php
  7. 13 0
      resources/views/distributor/filter/between.blade.php
  8. 24 0
      resources/views/distributor/filter/button.blade.php
  9. 19 0
      resources/views/distributor/filter/checkbox.blade.php
  10. 33 0
      resources/views/distributor/filter/container.blade.php
  11. 24 0
      resources/views/distributor/filter/datetime.blade.php
  12. 3 0
      resources/views/distributor/filter/gt.blade.php
  13. 3 0
      resources/views/distributor/filter/lt.blade.php
  14. 31 0
      resources/views/distributor/filter/multipleselect.blade.php
  15. 19 0
      resources/views/distributor/filter/radio.blade.php
  16. 26 0
      resources/views/distributor/filter/right-side-container.blade.php
  17. 30 0
      resources/views/distributor/filter/select.blade.php
  18. 16 0
      resources/views/distributor/filter/selecttable.blade.php
  19. 27 0
      resources/views/distributor/filter/simple-container.blade.php
  20. 19 0
      resources/views/distributor/filter/text.blade.php
  21. 3 0
      resources/views/distributor/filter/where.blade.php
  22. 100 0
      resources/views/distributor/form/autocomplete.blade.php
  23. 8 0
      resources/views/distributor/form/button.blade.php
  24. 27 0
      resources/views/distributor/form/captcha.blade.php
  25. 58 0
      resources/views/distributor/form/checkbox.blade.php
  26. 32 0
      resources/views/distributor/form/color.blade.php
  27. 18 0
      resources/views/distributor/form/container.blade.php
  28. 46 0
      resources/views/distributor/form/daterange.blade.php
  29. 47 0
      resources/views/distributor/form/datetimerange.blade.php
  30. 13 0
      resources/views/distributor/form/display.blade.php
  31. 30 0
      resources/views/distributor/form/editor.blade.php
  32. 25 0
      resources/views/distributor/form/embeds.blade.php
  33. 1 0
      resources/views/distributor/form/error.blade.php
  34. 10 0
      resources/views/distributor/form/extend/distpicker/filter.blade.php
  35. 21 0
      resources/views/distributor/form/extend/distpicker/select.blade.php
  36. 580 0
      resources/views/distributor/form/extend/diy-form/form.blade.php
  37. 197 0
      resources/views/distributor/form/extend/diy-form/show.blade.php
  38. 19 0
      resources/views/distributor/form/fields.blade.php
  39. 119 0
      resources/views/distributor/form/file.blade.php
  40. 24 0
      resources/views/distributor/form/footer.blade.php
  41. 86 0
      resources/views/distributor/form/hasmany.blade.php
  42. 104 0
      resources/views/distributor/form/hasmanytab.blade.php
  43. 112 0
      resources/views/distributor/form/hasmanytable.blade.php
  44. 5 0
      resources/views/distributor/form/help-block.blade.php
  45. 1 0
      resources/views/distributor/form/hidden.blade.php
  46. 10 0
      resources/views/distributor/form/id.blade.php
  47. 26 0
      resources/views/distributor/form/input.blade.php
  48. 112 0
      resources/views/distributor/form/keyvalue.blade.php
  49. 23 0
      resources/views/distributor/form/listbox.blade.php
  50. 85 0
      resources/views/distributor/form/listfield.blade.php
  51. 274 0
      resources/views/distributor/form/map.blade.php
  52. 33 0
      resources/views/distributor/form/markdown.blade.php
  53. 23 0
      resources/views/distributor/form/multipleselect.blade.php
  54. 34 0
      resources/views/distributor/form/number.blade.php
  55. 39 0
      resources/views/distributor/form/radio.blade.php
  56. 32 0
      resources/views/distributor/form/range.blade.php
  57. 17 0
      resources/views/distributor/form/rate.blade.php
  58. 7 0
      resources/views/distributor/form/row.blade.php
  59. 31 0
      resources/views/distributor/form/select-script.blade.php
  60. 35 0
      resources/views/distributor/form/select.blade.php
  61. 58 0
      resources/views/distributor/form/selecttable.blade.php
  62. 20 0
      resources/views/distributor/form/slider.blade.php
  63. 46 0
      resources/views/distributor/form/steps/completion-page.blade.php
  64. 10 0
      resources/views/distributor/form/steps/form.blade.php
  65. 310 0
      resources/views/distributor/form/steps/steps.blade.php
  66. 22 0
      resources/views/distributor/form/switchfield.blade.php
  67. 33 0
      resources/views/distributor/form/tab.blade.php
  68. 71 0
      resources/views/distributor/form/tags.blade.php
  69. 14 0
      resources/views/distributor/form/textarea.blade.php
  70. 47 0
      resources/views/distributor/form/timerange.blade.php
  71. 57 0
      resources/views/distributor/form/tree.blade.php
  72. 11 0
      resources/views/distributor/form/upload-img-demo.blade.php
  73. 189 0
      resources/views/distributor/grid/async-fixed-table.blade.php
  74. 87 0
      resources/views/distributor/grid/async-table.blade.php
  75. 37 0
      resources/views/distributor/grid/batch-actions.blade.php
  76. 54 0
      resources/views/distributor/grid/column-selector.blade.php
  77. 111 0
      resources/views/distributor/grid/displayer/dialogtree.blade.php
  78. 15 0
      resources/views/distributor/grid/displayer/editinline/checkbox.blade.php
  79. 17 0
      resources/views/distributor/grid/displayer/editinline/input.blade.php
  80. 15 0
      resources/views/distributor/grid/displayer/editinline/radio.blade.php
  81. 178 0
      resources/views/distributor/grid/displayer/editinline/template.blade.php
  82. 11 0
      resources/views/distributor/grid/displayer/editinline/textarea.blade.php
  83. 47 0
      resources/views/distributor/grid/displayer/expand.blade.php
  84. 20 0
      resources/views/distributor/grid/displayer/extensions/description.blade.php
  85. 60 0
      resources/views/distributor/grid/displayer/extensions/name.blade.php
  86. 44 0
      resources/views/distributor/grid/displayer/select.blade.php
  87. 51 0
      resources/views/distributor/grid/displayer/switch.blade.php
  88. 69 0
      resources/views/distributor/grid/displayer/switchgroup.blade.php
  89. 18 0
      resources/views/distributor/grid/displayer/table.blade.php
  90. 24 0
      resources/views/distributor/grid/dropdown-actions.blade.php
  91. 146 0
      resources/views/distributor/grid/fixed-table.blade.php
  92. 51 0
      resources/views/distributor/grid/image.blade.php
  93. 35 0
      resources/views/distributor/grid/pagination.blade.php
  94. 3 0
      resources/views/distributor/grid/quick-create/date.blade.php
  95. 88 0
      resources/views/distributor/grid/quick-create/form.blade.php
  96. 10 0
      resources/views/distributor/grid/quick-create/multipleselect.blade.php
  97. 12 0
      resources/views/distributor/grid/quick-create/select.blade.php
  98. 15 0
      resources/views/distributor/grid/quick-create/selectresource.blade.php
  99. 8 0
      resources/views/distributor/grid/quick-create/tags.blade.php
  100. 3 0
      resources/views/distributor/grid/quick-create/text.blade.php

+ 43 - 0
resources/views/distributor/dashboard/author.blade.php

@@ -0,0 +1,43 @@
+<style>
+    .dashboard-title .links {
+        text-align: center;
+        margin-bottom: 2.5rem;
+    }
+    .dashboard-title .links > a {
+        padding: 0 25px;
+        font-size: 12px;
+        font-weight: 600;
+        letter-spacing: .1rem;
+        text-decoration: none;
+        text-transform: uppercase;
+        color: #fff;
+    }
+    .dashboard-title h1 {
+        font-weight: 200;
+        font-size: 2.5rem;
+    }
+    .dashboard-title .avatar {
+        background: #fff;
+        border: 2px solid #fff;
+        width: 70px;
+        height: 70px;
+    }
+</style>
+
+<div class="dashboard-title card bg-primary">
+    <div class="card-body">
+        <div class="text-center ">
+            <img class="avatar img-circle shadow mt-1" src="https://m.saishiyun.net/imgpic/work-photo.png">
+            <div class="text-center mb-1">
+                <div class="mb-1 mt-1 text-white">微信号:Q3664839</div>
+                <h1 class="mb-1 mt-1 text-white">杨光</h1>
+                <div class="links">
+                    <a href="https://www.saishiyun.net" target="_blank">个人博客</a>
+                    {{--<a href="http://www.dcatadmin.com/" id="doc-link" target="_blank">{{ __('admin.documentation') }}</a>
+                    <a href="http://www.dcatadmin.com/" id="demo-link" target="_blank">{{ __('admin.extensions') }}</a>
+                    <a href="https://jqhph.github.io/dcat-admin/demo.html" id="demo-link" target="_blank"></a>--}}
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 15 - 0
resources/views/distributor/dashboard/dependencies.blade.php

@@ -0,0 +1,15 @@
+<style>
+    .table tr:first-child td {
+        border-top: 0;
+    }
+</style>
+<div class="table-responsive">
+    <table class="table">
+        @foreach($dependencies as $dependency => $version)
+            <tr>
+                <td width="240px" class="bold text-80">{{ $dependency }}</td>
+                <td><span class="label bg-primary">{{ $version }}</span></td>
+            </tr>
+        @endforeach
+    </table>
+</div>

+ 11 - 0
resources/views/distributor/dashboard/environment.blade.php

@@ -0,0 +1,11 @@
+<div class="table-responsive">
+    <table class="table">
+
+        @foreach($envs as $env)
+            <tr>
+                <td width="120px" class="bold text-80">{{ $env['name'] }}</td>
+                <td>{{ $env['value'] }}</td>
+            </tr>
+        @endforeach
+    </table>
+</div>

+ 52 - 0
resources/views/distributor/dashboard/extensions.blade.php

@@ -0,0 +1,52 @@
+<style>
+    .ext-icon {
+        color: rgba(0,0,0,0.5);
+        margin-left: 10px;
+    }
+    .installed {
+        color: #00a65a;
+        margin-right: 15px;
+        font-size:20px;
+    }
+</style>
+<ul class="products-list product-list-in-box" id="extension-box" style="margin-top:10px;min-height: 100px">
+    @foreach($extensions as $extension)
+        <li class="item hidden">
+            <div class="product-img">
+                <i class="{{$extension['icon']}} fa-2x ext-icon"></i>
+            </div>
+            <div class="product-info" data-key="{{$extension['key']}}">
+                <a href="{{ $extension['link'] }}" target="_blank" class="">
+                    {{ $extension['name'] }}
+                </a>
+                @if($extension['installed'])
+                    <span class="pull-right installed"><i class="ti-check"></i></span>
+                @endif
+            </div>
+        </li>
+@endforeach
+
+</ul>
+
+<div class="box-footer text-center">
+    <a href="https://github.com/jqhph/dcat-admin#%E6%89%A9%E5%B1%95" target="_blank" class="uppercase">View All Extensions</a>
+</div>
+
+<script>Dcat.ready(function () {
+    // var $box = $('#extension-box');
+    // $box.loading();
+    //
+    // $.ajax({
+    //     url: 'https://jqhph.github.io/dcat-admin/extra/extensions.html',
+    //     success: function (response) {
+    //         $box.loading(false);
+    //
+    //         $box.html(response);
+    //     },
+    //     error: function () {
+    //         $box.loading(false);
+    //
+    //         $box.find('.item').removeClass('hidden');
+    //     }
+    // });
+})</script>

+ 43 - 0
resources/views/distributor/dashboard/title.blade.php

@@ -0,0 +1,43 @@
+<style>
+    .dashboard-title .links {
+        text-align: center;
+        margin-bottom: 2.5rem;
+    }
+    .dashboard-title .links > a {
+        padding: 0 25px;
+        font-size: 12px;
+        font-weight: 600;
+        letter-spacing: .1rem;
+        text-decoration: none;
+        text-transform: uppercase;
+        color: #fff;
+    }
+    .dashboard-title h1 {
+        font-weight: 200;
+        font-size: 2.5rem;
+    }
+    .dashboard-title .avatar {
+        background: #fff;
+        border: 2px solid #fff;
+        width: 70px;
+        height: 70px;
+    }
+</style>
+
+<div class="dashboard-title card bg-primary">
+    <div class="card-body">
+        <div class="text-center ">
+            <img class="avatar img-circle shadow mt-1" src="{{ admin_asset('@admin/images/logo.png') }}">
+
+            <div class="text-center mb-1">
+                <h1 class="mb-3 mt-2 text-white">Dcat Admin</h1>
+                <div class="links">
+                    <a href="https://github.com/jqhph/dcat-admin" target="_blank">Github</a>
+                    <a href="http://www.dcatadmin.com/" id="doc-link" target="_blank">{{ __('admin.documentation') }}</a>
+                    <a href="http://www.dcatadmin.com/" id="demo-link" target="_blank">{{ __('admin.extensions') }}</a>
+                    <a href="https://jqhph.github.io/dcat-admin/demo.html" id="demo-link" target="_blank">{{ __('admin.demo') }}</a>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 27 - 0
resources/views/distributor/filter/between-datetime.blade.php

@@ -0,0 +1,27 @@
+<div class="filter-input col-sm-{{ $width }}"  style="{!! $style !!}">
+    <div class="form-group">
+        <div class="input-group input-group-sm">
+
+            <div class="input-group-prepend">
+                <span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b>&nbsp;<i class="feather icon-calendar"></i></span>
+            </div>
+
+            <input autocomplete="off" type="text" class="form-control" id="{{$id['start']}}" placeholder="{{$label}}" name="{{$name['start']}}" value="{{ request($name['start'], \Illuminate\Support\Arr::get($value, 'start')) }}">
+            <span class="input-group-addon" style="border-left: 0; border-right: 0;">To</span>
+            <input autocomplete="off" type="text" class="form-control" id="{{$id['end']}}" placeholder="{{$label}}" name="{{$name['end']}}" value="{{ request($name['end'], \Illuminate\Support\Arr::get($value, 'end')) }}">
+        </div>
+    </div>
+</div>
+
+<script require="@moment,@bootstrap-datetimepicker">
+    var options = {!! admin_javascript_json($dateOptions) !!};
+
+    $('#{{ $id['start'] }}').datetimepicker(options);
+    $('#{{ $id['end'] }}').datetimepicker($.extend(options, {useCurrent: false}));
+    $("#{{ $id['start'] }}").on("dp.change", function (e) {
+        $('#{{ $id['end'] }}').data("DateTimePicker").minDate(e.date);
+    });
+    $("#{{ $id['end'] }}").on("dp.change", function (e) {
+        $('#{{ $id['start'] }}').data("DateTimePicker").maxDate(e.date);
+    });
+</script>

+ 13 - 0
resources/views/distributor/filter/between.blade.php

@@ -0,0 +1,13 @@
+<div class="filter-input col-sm-{{ $width }} "  style="{!! $style !!}">
+    <div class="form-group" >
+        <div class="input-group input-group-sm">
+            <div class="input-group-prepend">
+                <span class="input-group-text text-capitalize bg-white"><b>{!! $label !!}</b></span>
+            </div>
+
+            <input type="text" class="form-control" placeholder="{{$label}}" name="{{$name['start']}}" value="{{ request($name['start'], \Illuminate\Support\Arr::get($value, 'start')) }}">
+            <span class="input-group-addon" style="border-left: 0; border-right: 0;">To</span>
+            <input type="text" class="form-control" placeholder="{{$label}}" name="{{$name['end']}}" value="{{ request($name['end'], \Illuminate\Support\Arr::get($value, 'end')) }}">
+        </div>
+    </div>
+</div>

+ 24 - 0
resources/views/distributor/filter/button.blade.php

@@ -0,0 +1,24 @@
+<div class="btn-group filter-button-group dropdown" style="margin-right:3px">
+    <button
+            class="btn btn-primary {{ $btn_class }}"
+            @if($only_scopes)data-toggle="dropdown"@endif
+            @if($scopes->isNotEmpty()) style="border-right: 0" @endif
+    >
+        <i class="feather icon-filter"></i>@if($filter_text)<span class="d-none d-sm-inline">&nbsp;&nbsp;{{ trans('admin.filter') }}</span>@endif
+
+        <span class="filter-count">@if($valueCount) &nbsp;({!! $valueCount !!}) @endif</span>
+    </button>
+    @if($scopes->isNotEmpty())
+        <ul class="dropdown-menu" role="menu">
+            @foreach($scopes as $scope)
+                {!! $scope->render() !!}
+            @endforeach
+            <li role="separator" class="dropdown-divider"></li>
+            <li class="dropdown-item"><a href="{{ $url_no_scopes }}">{{ trans('admin.cancel') }}</a></li>
+        </ul>
+        <button type="button" class="btn btn-primary" data-toggle="dropdown" style="border-left: 0">
+            @if($current_label) <span>{{ $current_label }}&nbsp;</span>@endif <i class="feather icon-chevron-down"></i>
+        </button>
+    @endif
+</div>
+

+ 19 - 0
resources/views/distributor/filter/checkbox.blade.php

@@ -0,0 +1,19 @@
+<div class="input-group input-group-sm">
+    @php
+        $checkbox = new \Dcat\Admin\Widgets\Checkbox($name.'[]', $options);
+        if ($inline) $checkbox->inline();
+
+        $checkbox->check(request($name, is_null($value) ? [] : $value))->circle(false);
+
+    @endphp
+    @if($showLabel)
+        <div class="pull-left text-capitalize" style="margin-top: 6px;margin-right: 15px;">
+            <b>{{ $label }}</b>
+        </div>
+        <div class="pull-left">
+            {!! $checkbox !!}
+        </div>
+    @else
+        {!! $checkbox !!}
+    @endif
+</div>

+ 33 - 0
resources/views/distributor/filter/container.blade.php

@@ -0,0 +1,33 @@
+<style>
+    .filter-box {
+        border-top: 1px solid #eee;
+        margin-top: 10px;
+        margin-bottom: -.5rem!important;
+        padding: 1.8rem;
+    }
+</style>
+
+<div class="filter-box shadow-0 card mb-0 {{ $expand ? '' : 'd-none' }} {{$containerClass}}">
+    <div class="card-body" style="{!! $style !!}"  id="{{ $filterID }}">
+        <form action="{!! $action !!}" class="form-horizontal grid-filter-form" pjax-container method="get">
+            <div class="row mb-0">
+                @foreach($layout->columns() as $column)
+                    @foreach($column->filters() as $filter)
+                        {!! $filter->render() !!}
+                    @endforeach
+                @endforeach
+
+                <button class="btn btn-primary btn-sm btn-mini submit" style="margin-left: 12px">
+                    <i class="feather icon-search"></i><span class="d-none d-sm-inline">&nbsp;&nbsp;{{ trans('admin.search') }}</span>
+                </button>
+
+                @if(!$disableResetButton)
+                <a style="margin-left: 6px" href="{!! $action !!}" class="reset btn btn-white btn-sm ">
+                    <i class="feather icon-rotate-ccw"></i><span class="d-none d-sm-inline">&nbsp;&nbsp;{{ trans('admin.reset') }}</span>
+                </a>
+                @endif
+            </div>
+
+        </form>
+    </div>
+</div>

+ 24 - 0
resources/views/distributor/filter/datetime.blade.php

@@ -0,0 +1,24 @@
+<div class="input-group input-group-sm">
+    @if($group)
+        <div class="input-group-prepend dropdown">
+            <a class="filter-group input-group-text bg-white dropdown-toggle" data-toggle="dropdown">
+                <span class="{{ $group_name }}-label">{{ $default['label'] }}&nbsp; </span>
+            </a>
+            <input type="hidden" name="{{ $id }}_group" class="{{ $group_name }}-operation" value="{{ request($id.'_group', 0) }}" />
+            <ul class="dropdown-menu {{ $group_name }}">
+                @foreach($group as $index => $item)
+                    <li class="dropdown-item"><a href="#" data-index="{{ $index }}"> {{ $item['label'] }} </a></li>
+                @endforeach
+            </ul>
+        </div>
+    @endif
+
+    <div class="input-group-prepend">
+        <span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b>&nbsp;<i class="feather icon-calendar"></i></span>
+    </div>
+    <input class="form-control" id="{{$id}}" autocomplete="off" placeholder="{{$label}}" name="{{$name}}" value="{{ request($name, $value) }}">
+</div>
+
+<script require="@moment,@bootstrap-datetimepicker">
+    $('#{{ $id }}').datetimepicker({!! admin_javascript_json($options) !!});
+</script>

+ 3 - 0
resources/views/distributor/filter/gt.blade.php

@@ -0,0 +1,3 @@
+<div class="filter-input col-sm-{{ $width }} " >
+    <div class="form-group">{!! $presenter() !!}</div>
+</div>

+ 3 - 0
resources/views/distributor/filter/lt.blade.php

@@ -0,0 +1,3 @@
+<div class="filter-input col-sm-{{ $width }} " >
+    <div class="form-group">{!! $presenter() !!}</div>
+</div>

+ 31 - 0
resources/views/distributor/filter/multipleselect.blade.php

@@ -0,0 +1,31 @@
+<div class="input-group input-group-sm">
+    <div class="input-group-prepend">
+        <span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b></span>
+    </div>
+
+    <select class="form-control {{ $class }}" name="{{$name}}[]" multiple style="width: 100%;" data-value="{{implode(',',(array) $value)}}">
+        @foreach($options as $select => $option)
+            <option value="{{$select}}" {{ in_array((string)$select, (array) $value)  ?'selected':'' }}>{{$option}}</option>
+        @endforeach
+    </select>
+</div>
+
+@include('admin::scripts.select')
+
+<script require="@select2?lang={{ config('app.locale') === 'en' ? '' : str_replace('_', '-', config('app.locale')) }}">
+    var configs = {!! admin_javascript_json($configs) !!};
+
+    @yield('admin.select-ajax')
+
+    @if(isset($remote))
+    $.ajax({!! admin_javascript_json($remote['ajaxOptions']) !!}).done(function(data) {
+        $("{{ $selector }}").select2($.extend({!! admin_javascript_json($configs) !!}, {
+            data: data,
+        })).val({!! json_encode($remote['values']) !!}).trigger("change");
+    });
+    @else
+    $("{!! $selector !!}").select2(configs);
+    @endif
+</script>
+
+@yield('admin.select-load')

+ 19 - 0
resources/views/distributor/filter/radio.blade.php

@@ -0,0 +1,19 @@
+<div class="input-group input-group-sm">
+    @php
+        $radio = new \Dcat\Admin\Widgets\Radio($name, $options);
+        if ($inline) $radio->inline();
+
+        $radio->check(request($name, is_null($value) ? [] : $value));
+
+    @endphp
+    @if($showLabel)
+        <div class="pull-left text-capitalize" style="margin-top: 6px;margin-right: 15px;">
+            <b>{{ $label }}</b>
+        </div>
+        <div class="pull-left">
+            {!! $radio !!}
+        </div>
+    @else
+        {!! $radio !!}
+    @endif
+</div>

+ 26 - 0
resources/views/distributor/filter/right-side-container.blade.php

@@ -0,0 +1,26 @@
+<div class="hidden">
+    <div class="filter-box right-side-filter-container" style="{!! $style !!}"  id="{{ $filterID }}">
+        <form action="{!! $action !!}" class="form-horizontal grid-filter-form" pjax-container method="get">
+            <div class="mb-1" style="height: 55px">
+                <div class="p-1 position-fixed d-flex justify-content-between header">
+                    <div>
+                        <button type="submit" class=" btn btn-sm btn-primary submit">
+                            <i class="feather icon-search"></i> &nbsp;{{ __('admin.search') }}
+                        </button>&nbsp;
+                        @if(!$disableResetButton)
+                            <a href="{!! $action !!}" class="reset btn btn-sm btn-white">
+                                <i class="feather icon-rotate-ccw"></i> &nbsp;{{ __('admin.reset') }}
+                            </a>
+                        @endif
+                    </div>
+                </div>
+            </div>
+
+            @foreach($layout->columns() as $column)
+                @foreach($column->filters() as $filter)
+                    {!! $filter->render() !!}
+                @endforeach
+            @endforeach
+        </form>
+    </div>
+</div>

+ 30 - 0
resources/views/distributor/filter/select.blade.php

@@ -0,0 +1,30 @@
+<div class="input-group input-group-sm">
+    <div class="input-group-prepend">
+        <span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b></span>
+    </div>
+
+    <select class="form-control {{ $class }}" name="{{$name}}" data-value="{{ $value }}" style="width: 100%;">
+        <option value=""></option>
+        @foreach($options as $select => $option)
+            <option value="{{$select}}" {{ Dcat\Admin\Support\Helper::equal($select, $value) ?'selected':'' }}>{{$option}}</option>
+        @endforeach
+    </select>
+</div>
+
+@include('admin::scripts.select')
+
+<script require="@select2?lang={{ config('app.locale') === 'en' ? '' : str_replace('_', '-', config('app.locale')) }}">
+    var configs = {!! admin_javascript_json($configs) !!};
+
+    @yield('admin.select-ajax')
+
+    @if(isset($remote))
+    $.ajax({!! admin_javascript_json($remote['ajaxOptions']) !!}).done(function(data) {
+        $("{{ $selector }}").select2($.extend({!! admin_javascript_json($configs) !!}, {
+            data: data,
+        })).val({!! json_encode($remote['values']) !!}).trigger("change");
+    });
+    @else
+    $("{!! $selector !!}").select2(configs);
+    @endif
+</script>

+ 16 - 0
resources/views/distributor/filter/selecttable.blade.php

@@ -0,0 +1,16 @@
+<div class="input-group input-group-sm">
+    <div class="input-group-prepend">
+        <span class="input-group-text bg-white"><b>{!! $label !!}</b></span>
+    </div>
+
+    <div id="{{ $id }}" class="form-control">
+        <span class="default-text" style="opacity:0.75">{{ $placeholder }}</span>
+        <span class="option d-none"></span>
+    </div>
+
+    <input name="{{ $name }}" type="hidden" id="hidden-{{ $id }}" value="{{ implode(',', \Dcat\Admin\Support\Helper::array($value)) }}" />
+    <div class="input-group-append">
+        {!! $dialog !!}
+    </div>
+
+</div>

+ 27 - 0
resources/views/distributor/filter/simple-container.blade.php

@@ -0,0 +1,27 @@
+<div class="filter-box card p-2 {{ $expand ? '' : 'd-none' }} {{$containerClass}}" style="padding-bottom: .5rem!important;margin-top: 10px;margin-bottom: 8px;box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.04);">
+    <div class="card-body" style="{!! $style !!}"  id="{{ $filterID }}">
+        <form action="{!! $action !!}" class="form-horizontal grid-filter-form" pjax-container method="get">
+            <div class="row mt-1 mb-0">
+                @foreach($layout->columns() as $column)
+                    @foreach($column->filters() as $filter)
+                        {!! $filter->render() !!}
+                    @endforeach
+                @endforeach
+
+                <div class="btn-group ml-1 mb-1" style="height: fit-content;margin-right: 10px">
+                    <button class="btn btn-primary btn-sm btn-mini submit">
+                        <i class="feather icon-search"></i><span class="d-none d-sm-inline">&nbsp;&nbsp;{{ trans('admin.search') }}</span>
+                    </button>
+                </div>
+                <div class="btn-group btn-group-sm default btn-mini" style="height: fit-content"  >
+                    @if(!$disableResetButton)
+                        <a  href="{!! $action !!}" class="reset btn btn-white btn-sm ">
+                            <i class="feather icon-rotate-ccw"></i><span class="d-none d-sm-inline">&nbsp;&nbsp;{{ trans('admin.reset') }}</span>
+                        </a>
+                    @endif
+                </div>
+            </div>
+
+        </form>
+    </div>
+</div>

+ 19 - 0
resources/views/distributor/filter/text.blade.php

@@ -0,0 +1,19 @@
+<div class="input-group input-group-sm">
+    @if($group)
+        <div class="input-group-prepend dropdown">
+            <a class="filter-group input-group-text bg-white dropdown-toggle" data-toggle="dropdown">
+                <span class="{{ $group_name }}-label">{{ $default['label'] }}&nbsp; </span>
+            </a>
+            <input type="hidden" name="{{ $id }}_group" class="{{ $group_name }}-operation" value="{{ request($id.'_group', 0) }}"/>
+            <ul class="dropdown-menu {{ $group_name }}">
+                @foreach($group as $index => $item)
+                    <li class="dropdown-item"><a  data-index="{{ $index }}"> {{ $item['label'] }} </a></li>
+                @endforeach
+            </ul>
+        </div>
+    @endif
+    <div class="input-group-prepend">
+        <span class="input-group-text bg-white text-capitalize"><b>{!! $label !!}</b></span>
+    </div>
+    <input type="{{ $type }}" class="form-control {{ $id }}" placeholder="{{$placeholder}}" name="{{$name}}" value="{{ request($name, $value) }}">
+</div>

+ 3 - 0
resources/views/distributor/filter/where.blade.php

@@ -0,0 +1,3 @@
+<div class="filter-input col-sm-{{ $width }} " style="{!! $style !!}">
+    <div class="form-group">{!! $presenter() !!}</div>
+</div>

+ 100 - 0
resources/views/distributor/form/autocomplete.blade.php

@@ -0,0 +1,100 @@
+<style>
+    .autocomplete-suggestions { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; border: 1px solid #999; background: #FFF; cursor: default; overflow: auto; -webkit-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); -moz-box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); box-shadow: 1px 4px 3px rgba(50, 50, 50, 0.64); }
+    .autocomplete-suggestion { padding: 2px 5px; white-space: nowrap; overflow: hidden; }
+    .autocomplete-no-suggestion { padding: 2px 5px;}
+    .autocomplete-selected { background: #F0F0F0; }
+    .autocomplete-suggestions strong { font-weight: bold; color: #000; }
+    .autocomplete-group { padding: 2px 5px; font-weight: bold; font-size: 16px; color: #000; display: block; border-bottom: 1px solid #000; }
+</style>
+
+@include('admin::form.input')
+
+<script init="{!! $selector !!}" require="@autocomplete">
+
+    var configs = {!! $configs !!};
+
+    @if(isset($ajax))
+
+    configs = $.extend(configs, {
+
+        serviceUrl: '{{ $ajax['url'] }}',
+        groupBy: '{{ $ajax['groupField'] }}',
+        dataType: 'json',
+        transformResult: function (response) {
+            return {
+                suggestions: (function (data, valueField) {
+                    if (!data) {
+                        return [];
+                    }
+
+                    if (valueField) {
+                        return $.map(data, function (dat) {
+                            return {value: Dcat.helpers.get(dat, valueField) + '', data: dat};
+                        });
+                    }
+
+                    return data;
+                })(response.data, '{{ $ajax['valueField'] }}')
+            };
+        }
+    });
+    @else
+    configs = $.extend(configs, {
+        lookup: {!! $options !!}
+    });
+    @endif
+
+    @if(isset($depends))
+
+    var fields = {!! $depends['fields'] !!};
+
+    configs = $.extend(configs, {
+        'onSearchStart': function (params) {
+
+            var formData = $this.closest('form').serializeArray();
+
+            var p = {};
+
+            for (var field of fields) {
+                for (var data of formData) {
+                    if (!data.value.length){
+                        continue;
+                    }
+                    if (data.name === field) {
+                        p[field] = data.value
+                    }
+                    if (data.name === field + '[]') {
+                        if(!Array.isArray(p[field])){
+                            p[field] = []
+                        }
+                        p[field].push(data.value);
+                    }
+                }
+                if (!p.hasOwnProperty(field)){
+                    return false;
+                }
+            }
+
+            params = $.extend(params, p);
+        }
+    })
+
+    @if($depends['clear'])
+    $.map(fields, function (field) {
+        var _selectors = [
+            '[name="' + field + '"]',
+            '[name="' + field + '[]"]'
+        ];
+        $.map(_selectors, function(_selector){
+            $this.closest('form').off('change.depends', _selector)
+                .on('change.depends', _selector, function () {
+                    $this.val('');
+                });
+        })
+    });
+    @endif
+
+    @endif
+
+    $this.autocomplete(configs);
+</script>

+ 8 - 0
resources/views/distributor/form/button.blade.php

@@ -0,0 +1,8 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label"></label>
+
+    <div class="{{$viewClass['field']}}">
+        <span class="btn {{ $class }} {{ $buttonClass }}" {!! $attributes !!}>{!! $label !!}</span>
+    </div>
+</div>

+ 27 - 0
resources/views/distributor/form/captcha.blade.php

@@ -0,0 +1,27 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="input-group" style="width: 250px;">
+
+            <input {!! $attributes !!} />
+
+            <span class="input-group-addon clearfix" style="padding: 1px;">
+                <img class="field-refresh-captcha" data-url="{{ $captchaSrc }}" src="{{ $captchaSrc }}" style="height:30px;cursor: pointer;"  title="Click to refresh"/>
+            </span>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script init=".field-refresh-captcha" once>
+    $this.off('click').on('click', function () {
+        $(this).attr('src', $(this).attr('data-url')+'?'+Math.random());
+    });
+</script>

+ 58 - 0
resources/views/distributor/form/checkbox.blade.php

@@ -0,0 +1,58 @@
+<div class="{{$viewClass['form-group']}}" >
+
+    <label class="{{$viewClass['label']}} control-label pt-0">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @if($checkAll)
+            {!! $checkAll !!}
+            <hr style="margin-top: 10px;margin-bottom: 0;">
+        @endif
+
+        @include('admin::form.error')
+
+        {!! $checkbox !!}
+
+        <input type="hidden" name="{{$name}}[]">
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+@if(! empty($canCheckAll))
+<script init="[name='_check_all_']" once>
+    $this.on('change', function () {
+        $(this).parents('.form-field').find('input[type="checkbox"]:not(:first)').prop('checked', this.checked).trigger('change');
+    });
+</script>
+@endif
+
+@if(! empty($loads))
+<script once>
+    var selector = '{!! $selector !!}',
+        fields = '{!! $loads['fields'] !!}'.split('^'),
+        urls = '{!! $loads['urls'] !!}'.split('^');
+
+    $(document).off('change', selector);
+    $(document).on('change', selector, function () {
+        var values = [];
+
+        $(selector+':checked').each(function () {
+            if (String(this.value) === '0' || this.value) {
+                values.push(this.value)
+            }
+        });
+
+        Dcat.helpers.loadFields(this, {
+            group: '.fields-group',
+            urls: urls,
+            fields: fields,
+            textField: "{{ $loads['textField'] }}",
+            idField: "{{ $loads['idField'] }}",
+            values: values,
+        });
+    });
+    $(selector+':checked').trigger('change')
+</script>
+@endif

+ 32 - 0
resources/views/distributor/form/color.blade.php

@@ -0,0 +1,32 @@
+<style>
+    .popover{z-index:29891015}
+</style>
+
+<div class="{{$viewClass['form-group']}}">
+    <div  class="{{$viewClass['label']}} control-label">
+        <span>{!! $label !!}</span>
+    </div>
+
+    <div class="{{$viewClass['field']}}">
+        @include('admin::form.error')
+
+        <div class="input-group">
+
+            <span class="input-group-prepend"><span class="input-group-text bg-white" style="padding: 4px"><i style="width: 24px;height: 100%;background: {!! $value !!}"></i></span></span>
+
+            <input {!! $attributes !!} />
+
+            @if ($append)
+                <span class="input-group-append">{!! $append !!}</span>
+            @endif
+        </div>
+
+        @include('admin::form.help-block')
+    </div>
+</div>
+
+<script require="@color" init="{!! $selector !!}">
+    $this.colorpicker({!! admin_javascript_json($options) !!}).on('colorpickerChange', function(event) {
+        $(this).parents('.input-group').find('.input-group-prepend i').css('background-color', event.color.toString());
+    });
+</script>

+ 18 - 0
resources/views/distributor/form/container.blade.php

@@ -0,0 +1,18 @@
+@if($showHeader)
+    <div class="box-header with-border mb-1" style="padding: .65rem 1rem">
+        <h3 class="box-title" style="line-height:30px">{!! $form->title() !!}</h3>
+        <div class="pull-right">{!! $form->renderTools() !!}</div>
+    </div>
+@endif
+<div class="box-body" {!! $tabObj->isEmpty() && !$form->hasRows() ? 'style="margin-top: 6px"' : '' !!} >
+    @if(!$tabObj->isEmpty())
+        @include('admin::form.tab', compact('tabObj', 'form'))
+    @else
+        <div class="fields-group">
+            @include('admin::form.fields', ['rows' => $form->rows(), 'fields' => $form->fields(), 'layout' => $form->layout()])
+        </div>
+    @endif
+</div>
+{!! $form->renderFooter() !!}
+
+{!! $form->renderHiddenFields() !!}

+ 46 - 0
resources/views/distributor/form/daterange.blade.php

@@ -0,0 +1,46 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="row" style="max-width: 603px">
+            <div class="col-lg-6">
+                <div class="input-group">
+                     <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-calendar"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['start']}}" value="{{ $value['start'] ?? null }}" class="form-control {{$class['start']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+
+            <div class="col-lg-6">
+                <div class="input-group">
+                     <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-calendar"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['end']}}" value="{{ $value['end'] ?? null }}" class="form-control {{$class['end']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@moment,@bootstrap-datetimepicker" init="{!! $selector['start'] !!}">
+    var options = {!! admin_javascript_json($options) !!};
+    var $end = $('{!! $selector['end'] !!}');
+
+    $this.datetimepicker(options);
+    $end.datetimepicker($.extend(options, {useCurrent: false}));
+    $this.on("dp.change", function (e) {
+        $end.data("DateTimePicker").minDate(e.date);
+    });
+    $end.on("dp.change", function (e) {
+        $this.data("DateTimePicker").maxDate(e.date);
+    });
+</script>

+ 47 - 0
resources/views/distributor/form/datetimerange.blade.php

@@ -0,0 +1,47 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="row" style="max-width: 603px">
+            <div class="col-md-6" style="margin-right: 0">
+                <div class="input-group">
+                    <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-calendar"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['start']}}" value="{{ $value['start'] ?? null }}" class="form-control {{$class['start']}}" style="width:180px" {!! $attributes !!} />
+                </div>
+            </div>
+
+            <div class="col-md-6">
+                <div class="input-group">
+                    <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-calendar"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['end']}}" value="{{ $value['end'] ?? null }}" class="form-control {{$class['end']}}" style="width: 180px" {!! $attributes !!} />
+                </div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@moment,@bootstrap-datetimepicker" init="{!! $selector['start'] !!}">
+    var options = {!! admin_javascript_json($options) !!};
+    var $end = $('{!! $selector['end'] !!}');
+
+    $this.datetimepicker(options);
+    $end.datetimepicker($.extend(options, {useCurrent: false}));
+    $this.on("dp.change", function (e) {
+        $end.data("DateTimePicker").minDate(e.date);
+    });
+    $end.on("dp.change", function (e) {
+        $this.data("DateTimePicker").maxDate(e.date);
+    });
+</script>
+

+ 13 - 0
resources/views/distributor/form/display.blade.php

@@ -0,0 +1,13 @@
+<div class="{{$viewClass['form-group']}}" style="margin-top: .3rem">
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+    <div class="{{$viewClass['field']}}">
+        <div class="box box-solid box-default no-margin">
+            <div class="box-body">
+                <div class="{{$class}}">{!! $value !!}&nbsp;</div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 30 - 0
resources/views/distributor/form/editor.blade.php

@@ -0,0 +1,30 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <textarea class="form-control {{$class}}" name="{{$name}}" placeholder="{{ $placeholder }}" {!! $attributes !!} >{{ $value }}</textarea>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@tinymce" init="{!! $selector !!}">
+    var opts = {!! admin_javascript_json($options) !!};
+
+    opts.selector = '#'+id;
+
+    if (! opts.init_instance_callback) {
+        opts.init_instance_callback = function (editor) {
+            editor.on('Change', function(e) {
+                $this.val(String(e.target.getContent()).replace('<p><br data-mce-bogus="1"></p>', '').replace('<p><br></p>', ''));
+            });
+        }
+    }
+
+    tinymce.init(opts)
+</script>

+ 25 - 0
resources/views/distributor/form/embeds.blade.php

@@ -0,0 +1,25 @@
+@if($label!=false)
+<div class="row">
+    <div class="{{$viewClass['label']}}"><h4 class="pull-right">{!! $label !!}</h4></div>
+    <div class="{{$viewClass['field']}}"></div>
+</div>
+<hr style="margin-top: 0px;">
+@endif
+
+<div id="embed-{{$column}}" class="embed-{{$column}}">
+
+    <div class="embed-{{$column}}-forms">
+
+        <div class="embed-{{$column}}-form fields-group">
+
+            @foreach($form->fields() as $field)
+                {!! $field->render() !!}
+            @endforeach
+
+        </div>
+    </div>
+</div>
+
+@if($label!=false)
+<hr style="margin-top: 0px;">
+@endif

+ 1 - 0
resources/views/distributor/form/error.blade.php

@@ -0,0 +1 @@
+<div class="help-block with-errors"></div>

+ 10 - 0
resources/views/distributor/form/extend/distpicker/filter.blade.php

@@ -0,0 +1,10 @@
+<div class="filter-input">
+    <div class="input-group input-group-sm" id="{{ $id }}" data-value-type="code">
+        <div class="input-group-prepend">
+            <span class="input-group-text bg-white text-capitalize"  data-toggle="tooltip" data-placement="top"><b>{!! $label !!}</b></span>
+        </div>
+        @foreach($name as $viewClass)
+            <select class="form-control distpicker_select" name="{{$viewClass}}"></select>&nbsp;
+        @endforeach
+    </div>
+</div>

+ 21 - 0
resources/views/distributor/form/extend/distpicker/select.blade.php

@@ -0,0 +1,21 @@
+<div class="{{$viewClass['form-group']}} {!! !$errors->hasAny($errorKey) ? '' : 'has-error' !!}">
+    <label for="{{$id}}" class="{{$viewClass['label']}} control-label">{{$label}}</label>
+    <div class="{{$viewClass['field']}} form-inline">
+        @foreach($errorKey as $key => $col)
+            @if($errors->has($col))
+                @foreach($errors->get($col) as $message)
+                    <label class="control-label" for="inputError">
+                        <i class="fa fa-times-circle-o"></i> {{$message}}
+                    </label>
+                    <br/>
+                @endforeach
+            @endif
+        @endforeach
+        <div id="{{ $id }}" {!! $attributes !!}>
+            @foreach($name as $viewClass)
+                <select class="form-control" name="{{$viewClass}}"></select>&nbsp;
+            @endforeach
+        </div>
+        @include('admin::form.help-block')
+    </div>
+</div>

+ 580 - 0
resources/views/distributor/form/extend/diy-form/form.blade.php

@@ -0,0 +1,580 @@
+<style>
+    [v-cloak] {
+        display: none;
+    }
+
+    .diy-main {
+        background: #f7f7f7;
+        border-radius: .25rem;
+        padding: 5px 20px;
+        display: flex;
+        justify-content: space-around;
+        max-height: 600px;
+        min-width: 650px;
+    }
+
+    .diy-card {
+        background: #fff;
+        border-radius: .25rem;
+        padding: 15px;
+        margin: 5px;
+        overflow: auto;
+    }
+
+    .add-btn-div {
+        display: flex;
+        justify-content: end;
+        padding-top: 20px;
+    }
+
+    .type-item {
+        width: 100%;
+        border: 1px solid #f1f1f1;
+        padding: 5px;
+        border-radius: .25rem;
+        text-align: center;
+        margin: 10px 0;
+        cursor: pointer;
+    }
+
+    .type-item:hover {
+        border-color: {{ $theme_color }};
+    }
+
+    .type-item-active {
+        background: {{ Admin::color()->alpha($theme_color, 0.3) }};
+        border-color: transparent;
+    }
+
+    .card-label {
+        margin-bottom: 5px;
+        border-bottom: 1px solid #f7f7f7;
+        width: 100%;
+        padding-bottom: 5px;
+    }
+
+    .props-item {
+        padding: 3px 0;
+        display: flex;
+        align-items: center;
+    }
+
+    .props-label {
+        min-width: 60px;
+    }
+
+    .option-area {
+        background: #f7f7f7;
+        padding: 5px;
+        overflow: auto;
+        border-radius: .25rem;
+    }
+
+    .option-area > div:not(:last-child) {
+        margin-bottom: 3px;
+    }
+
+    .option-action {
+        font-size: 20px;
+        padding: 0 10px;
+        font-weight: bold;
+        cursor: pointer;
+        border: 1px solid #dbe3e6;
+        border-radius: 0.25rem;
+        background: #fff;
+    }
+
+    .option-action:hover {
+        background: #f7f7f7;
+    }
+
+    .cursor-pointer {
+        cursor: pointer;
+    }
+
+    .preview-item {
+        margin-top: 10px;
+    }
+
+    .move-item {
+        padding: 0 5px;
+        cursor: pointer;
+    }
+
+    .hover-line:hover {
+        border-bottom: 1px solid;
+    }
+</style>
+
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div {!! $attributes !!} style="width: 100%; height: 100%; overflow: auto" v-cloak>
+            <div class="diy-main">
+                {{--组件类型卡片--}}
+                <div class="diy-card col-4">
+                    <div class="form-group">
+                        <label class="card-label">组件类型</label>
+                        <div class="type-item"
+                             v-for="(item, index) in component_type"
+                             :key="index"
+                             :class="{'type-item-active': current_type.type == item.type}"
+                             v-on:click="selectType(item)">
+                            @{{ item.name }}
+                        </div>
+                    </div>
+                </div>
+
+                {{--属性卡片--}}
+                <div class="diy-card col-4 d-flex flex-column">
+                    <label class="card-label">属性</label>
+                    <div class="d-flex justify-content-between flex-column h-auto flex-grow-1">
+                        <div>
+                            <div v-if="current_type">
+                                <div class="props-item">
+                                    <div class="props-label">类型</div>
+                                    <div class="">@{{ current_type.name }}</div>
+                                </div>
+                                <div class="props-item">
+                                    <div class="props-label">标签</div>
+                                    <div class="">
+                                        <input type="text"
+                                               class="form-control form-control-sm"
+                                               v-model="current_type.label"
+                                               placeholder="请输入标签">
+                                    </div>
+                                </div>
+                                <div class="props-item">
+                                    <div class="props-label">必填</div>
+                                    <div class="">
+                                        <div class="custom-control custom-radio custom-control-inline">
+                                            <input type="radio"
+                                                   id="required_yes"
+                                                   name="need_required"
+                                                   value="1"
+                                                   v-model="current_type.required"
+                                                   class="custom-control-input">
+                                            <label class="custom-control-label" for="required_yes">
+                                                是
+                                            </label>
+                                        </div>
+                                        <div class="custom-control custom-radio custom-control-inline">
+                                            <input type="radio"
+                                                   id="required_no"
+                                                   name="need_required"
+                                                   value="0"
+                                                   v-model="current_type.required"
+                                                   class="custom-control-input">
+                                            <label class="custom-control-label" for="required_no">
+                                                否
+                                            </label>
+                                        </div>
+                                    </div>
+                                </div>
+                                <div class="props-item">
+                                    <div class="props-label">默认值</div>
+                                    <div class="">
+                                        <input type="text"
+                                               class="form-control form-control-sm"
+                                               v-model="current_type.default_value"
+                                               :placeholder="current_type.type == 'checkbox' ? '多个以,(英文逗号)分隔' : '请输入默认值'">
+                                    </div>
+                                </div>
+                                {{--自定义属性--}}
+                                <div class="props-item" v-for="(item, index) in current_type.props_items" :key="index">
+                                    <div class="props-label">@{{ item.label }}</div>
+                                    <div class="">
+                                        <input type="text"
+                                               class="form-control form-control-sm"
+                                               v-model="current_type[item.bind]"
+                                               :placeholder="`请输入${item.label}`">
+                                    </div>
+                                </div>
+                                {{--选项--}}
+                                <div class="props-item" v-if="current_type.options">
+                                    <div class="props-label">@{{ current_type.options.label }}</div>
+                                    <div class="option-area">
+                                        <div class="d-flex"
+                                             v-for="(item, index) in current_type.options.values"
+                                             :key="index">
+                                            <input type="text"
+                                                   class="form-control form-control-sm"
+                                                   v-model="current_type.options.values[index]">
+                                            <div class="option-action"
+                                                 v-if="index + 1 == current_type.options.values.length"
+                                                 v-on:click="addOptions">+
+                                            </div>
+                                            <div class="option-action"
+                                                 v-if="current_type.options.values.length > 1"
+                                                 v-on:click="subOptions(index)">-
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="add-btn-div">
+                            <button type="button" class="btn btn-primary" v-on:click="addItem">添加</button>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="diy-card col-4">
+                    <label class="card-label">预览</label>
+                    <div>
+                        <div v-for="(item, index) in contents" :key="index">
+                            {{--自定义预览html--}}
+                            {!! $preview_html !!}
+
+                            {{--input--}}
+                            <div class="preview-item" v-if="item.type == 'input'" :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <input type="text"
+                                           class="form-control form-control-sm"
+                                           :value="item.default_value"
+                                           :placeholder="`请输入${item.label}`">
+                                </div>
+                            </div>
+
+                            {{--textarea--}}
+                            <div class="preview-item" v-if="item.type == 'textarea'" :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <textarea class="form-control"
+                                              :rows="item.rows"
+                                              :value="item.default_value"></textarea>
+                                </div>
+                            </div>
+
+                            {{--radio--}}
+                            <div class="preview-item" v-if="item.type == 'radio'" :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <div class="custom-control custom-radio custom-control-inline"
+                                         v-for="(opt, opt_key) in item.options.values"
+                                         :key="opt_key">
+                                        <input type="radio"
+                                               :id="'radio_item_' + index + opt_key"
+                                               :name="'radio_' + index"
+                                               :checked="opt == item.default_value"
+                                               class="custom-control-input">
+                                        <label class="custom-control-label" :for="'radio_item_' + index + opt_key">
+                                            @{{ opt }}
+                                        </label>
+                                    </div>
+                                </div>
+                            </div>
+
+                            {{--checkbox--}}
+                            <div class="preview-item" v-if="item.type == 'checkbox'" :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <div class="custom-control custom-checkbox custom-control-inline"
+                                         v-for="(opt, opt_key) in item.options.values"
+                                         :key="opt_key">
+                                        <input type="checkbox"
+                                               class="custom-control-input"
+                                               :checked="item.default_value && item.default_value.split(',').indexOf(opt) > -1"
+                                               :id="'checkbox_item_' + index + opt_key">
+                                        <label class="custom-control-label" :for="'checkbox_item_' + index + opt_key">
+                                            @{{ opt }}
+                                        </label>
+                                    </div>
+                                </div>
+                            </div>
+
+                            {{--select--}}
+                            <div class="preview-item" v-if="item.type == 'select'" :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <select class="form-control form-control-sm">
+                                        <option
+                                            v-for="(opt, opt_key) in item.options.values"
+                                            :selected="opt == item.default_value"
+                                            :key="opt_key">
+                                            @{{ opt }}
+                                        </option>
+                                    </select>
+                                </div>
+                            </div>
+
+                            {{--upload--}}
+                            <div class="preview-item"
+                                 v-if="item.type == 'upload-image' || item.type == 'upload-vedio'"
+                                 :class="'animate-item-' + index">
+                                <label class="d-flex justify-content-between">
+                                    <div>
+                                        <span class="text-danger" v-if="item.required == 1">* </span>
+                                        @{{ item.label }}
+                                    </div>
+                                    <div>
+                                        <span class="move-item hover-line"
+                                              v-if="index != 0"
+                                              v-on:click="previewItemGoUp(index)">
+                                            <i class="feather icon-arrow-up"></i>
+                                        </span>
+                                        <span class="move-item hover-line"
+                                              v-if="index != contents.length - 1"
+                                              v-on:click="previewItemGoDown(index)">
+                                            <i class="feather icon-arrow-down"></i>
+                                        </span>
+                                        <span class="text-danger cursor-pointer hover-line"
+                                              v-on:click="subPreviewItem(index)">
+                                            移除
+                                        </span>
+                                    </div>
+                                </label>
+                                <div class="">
+                                    <button type="button" class="btn btn-default btn-sm" v-on:click="previewTips">
+                                        @{{ item.name }}
+                                    </button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+
+            <input type="hidden" name="{{$name}}" value="{{ old($column, $value) }}" v-model="submit_value"/>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script init="{!! $selector !!}">
+    new Vue({
+        el: `#${id}`,
+        data: {
+            component_type: {!! admin_javascript_json($component_type) !!},
+            contents: [],
+            current_type: '',
+            submit_value: '',
+        },
+        mounted() {
+            let edit_data = '{!! old($column, $value) !!}'
+
+            if (edit_data) {
+                this.contents = JSON.parse(edit_data)
+                this.submitValueHandler()
+            }
+        },
+        methods: {
+            // 添加组件
+            addItem() {
+                let data = this.current_type
+                if (!data) {
+                    return Dcat.error('请先选择组件类型')
+                }
+
+                if (!data.label) {
+                    return Dcat.error('请填写标签')
+                }
+
+                if (data.options) {
+                    if (data.options.values.length < 2) {
+                        return Dcat.error(`请至少添加两个${data.options.label}`)
+                    }
+
+                    let nullValue = 0
+                    data.options.values.forEach((item) => {
+                        if (item == '') {
+                            nullValue++
+                        }
+                    })
+
+                    if (nullValue > 0) {
+                        return Dcat.error(data.options.label + '不可为空')
+                    }
+                }
+
+                if (data.validate_handler) {
+                    let message = data.validate_handler(data)
+
+                    if (message) {
+                        return Dcat.error(message)
+                    }
+                }
+
+                this.contents.push(this.deepCopy(data))
+                this.current_type = ''
+                this.submitValueHandler()
+            },
+            // 选择组件类型
+            selectType(item) {
+                this.current_type = this.deepCopy(item)
+            },
+            // 添加选项
+            addOptions() {
+                this.current_type.options.values.push('')
+            },
+            // 移除选项
+            subOptions(index) {
+                this.current_type.options.values.splice(index, 1)
+            },
+            // 深拷贝
+            deepCopy(value) {
+                return JSON.parse(JSON.stringify(value))
+            },
+            // 预览功能提示
+            previewTips() {
+                Dcat.warning('功能预览, 无实际功能')
+            },
+            // 移除预览项
+            subPreviewItem(index) {
+                this.contents.splice(index, 1)
+                this.submitValueHandler()
+            },
+            // 预览项上移
+            previewItemGoUp(index) {
+                $('.animate-item-' + index).fadeOut('fast')
+                $('.animate-item-' + (index - 1)).fadeOut('fast')
+
+                setTimeout(() => {
+                    let temp = ''
+                    temp = this.contents[index]
+                    this.contents[index] = this.contents[index - 1]
+                    this.contents[index - 1] = temp
+                    this.$forceUpdate()
+                    this.submitValueHandler()
+
+                    $('.animate-item-' + index).fadeIn('fast')
+                    $('.animate-item-' + (index - 1)).fadeIn('fast')
+                }, 150)
+            },
+            // 预览项下移
+            previewItemGoDown(index) {
+                $('.animate-item-' + index).fadeOut('fast')
+                $('.animate-item-' + (index + 1)).fadeOut('fast')
+
+                setTimeout(() => {
+                    let temp = ''
+                    temp = this.contents[index]
+                    this.contents[index] = this.contents[index + 1]
+                    this.contents[index + 1] = temp
+                    this.$forceUpdate()
+                    this.submitValueHandler()
+
+                    $('.animate-item-' + index).fadeIn('fast')
+                    $('.animate-item-' + (index + 1)).fadeIn('fast')
+                }, 150)
+            },
+            submitValueHandler() {
+                this.submit_value = JSON.stringify(this.contents)
+            }
+        }
+    })
+</script>

+ 197 - 0
resources/views/distributor/form/extend/diy-form/show.blade.php

@@ -0,0 +1,197 @@
+<style>
+    [v-cloak] {
+        display: none;
+    }
+
+    .diy-card {
+        border-radius: .25rem;
+        /*padding: 15px;*/
+        /*margin: 5px;*/
+        overflow: auto;
+        position: relative;
+    }
+
+    .option-area > div:not(:last-child) {
+        margin-bottom: 3px;
+    }
+
+    .preview-item {
+        margin-top: 10px;
+    }
+
+    .the-mask {
+        width: 98%;
+        background: transparent;
+        height: 92%;
+        position: absolute;
+        z-index: 999;
+    }
+
+    /*.diy-main .form-control{*/
+    /*    width: 80%;*/
+    /*}*/
+</style>
+
+<div class="diy-main" v-cloak>
+    <div style="width: 100%; height: 100%; overflow: auto">
+        <div class="diy-card">
+            {{--            @if($show_mask)--}}
+            {{--                <div class="the-mask" onclick="maskTips()"></div>--}}
+            {{--            @endif--}}
+
+            <div v-for="(item, index) in contents" :key="index">
+                {{--自定义预览html--}}
+                {!! $preview_html !!}
+
+                {{--input--}}
+                <div class="preview-item" v-if="item.type == 'input'" :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <input type="text"
+                               class="form-control"
+                               :value="item.default_value"
+                               disabled
+                               :placeholder="`请输入${item.label}`">
+                    </div>
+                </div>
+
+                {{--textarea--}}
+                <div class="preview-item" v-if="item.type == 'textarea'" :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <textarea class="form-control"
+                                  :rows="item.rows"
+                                  disabled
+                                  :value="item.default_value"></textarea>
+                    </div>
+                </div>
+
+                {{--radio--}}
+                <div class="preview-item" v-if="item.type == 'radio'" :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <div class="custom-control custom-radio custom-control-inline"
+                             v-for="(opt, opt_key) in item.options.values"
+                             :key="opt_key">
+                            <input type="radio"
+                                   :id="'radio_item_' + index + opt_key"
+                                   :name="'radio_' + index"
+                                   :checked="opt == item.default_value"
+                                   disabled
+                                   class="custom-control-input">
+                            <label class="custom-control-label" :for="'radio_item_' + index + opt_key">
+                                @{{ opt }}
+                            </label>
+                        </div>
+                    </div>
+                </div>
+
+                {{--checkbox--}}
+                <div class="preview-item" v-if="item.type == 'checkbox'" :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <div class="custom-control custom-checkbox custom-control-inline"
+                             v-for="(opt, opt_key) in item.options.values"
+                             :key="opt_key">
+                            <input type="checkbox"
+                                   class="custom-control-input"
+                                   :checked="item.default_value ? item.default_value.split(',').indexOf(opt) > -1 : ''"
+                                   disabled
+                                   :id="'checkbox_item_' + index + opt_key">
+                            <label class="custom-control-label" :for="'checkbox_item_' + index + opt_key">
+                                @{{ opt }}
+                            </label>
+                        </div>
+                    </div>
+                </div>
+
+                {{--select--}}
+                <div class="preview-item" v-if="item.type == 'select'" :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <select class="form-control" disabled>
+                            <option
+                                    v-for="(opt, opt_key) in item.options.values"
+                                    :selected="opt == item.default_value"
+                                    :key="opt_key">
+                                @{{ opt }}
+                            </option>
+                        </select>
+                    </div>
+                </div>
+
+                {{--upload--}}
+                <div class="preview-item"
+                     v-if="item.type == 'upload-image' || item.type == 'upload-vedio'"
+                     :class="'animate-item-' + index">
+                    <label class="d-flex justify-content-between">
+                        <div>
+                            <span class="text-danger" v-if="item.required == 1">* </span>
+                            @{{ item.label }}
+                        </div>
+                    </label>
+                    <div class="">
+                        <div v-if="item.type == 'upload-image'">
+                            <img v-for="(vv, kk) in (item.default_value ? item.default_value.split(',') : [])" :key="kk" :src="vv" alt="" width="150px" height="150px" style="margin: 5px;">
+                        </div>
+                        <div v-else>
+                            <video v-for="(vvv, kkk) in (item.default_value ? item.default_value.split(',') : [])" :key="kkk" width="320" height="240" controls>
+                                <source :src="vvv" type="video/mp4">
+                                您的浏览器不支持 video 标签。
+                            </video>
+                        </div>
+                        {{--<button class="btn btn-default btn-sm" onclick="maskTips()">--}}
+                        {{--    @{{ item.name }}--}}
+                        {{--</button>--}}
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    Dcat.ready(function () {
+        $('.diy-main').parents('.box').css('border', 0).css('box-shadow', '0 0')
+        $('.diy-main').parents('.box-body').css('padding', 0)
+        $('.diy-main').parents('.col-sm-8').css('border-left', '1px solid ' + '{{ Admin::color()->primary() }}')
+
+        Dcat.init('.diy-main', function ($this, id) {
+            new Vue({
+                el: `#${id}`,
+                data: {
+                    contents: {!! $value !!}
+                },
+            })
+        })
+    })
+
+    function maskTips() {
+        Dcat.warning('暂不支持操作表单')
+    }
+</script>

+ 19 - 0
resources/views/distributor/form/fields.blade.php

@@ -0,0 +1,19 @@
+@if($rows)
+    <div class="ml-2 mb-2 mr-2" style="margin-top: -0.5rem">
+        @foreach($rows as $row)
+            {!! $row->render() !!}
+        @endforeach
+
+        @foreach($fields as $field)
+            @if($field instanceof Dcat\Admin\Form\Field\Hidden)
+                {!! $field->render() !!}
+            @endif
+        @endforeach
+    </div>
+@elseif($layout->hasColumns())
+    {!! $layout->build() !!}
+@else
+    @foreach($fields as $field)
+        {!! $field->render() !!}
+    @endforeach
+@endif

+ 119 - 0
resources/views/distributor/form/file.blade.php

@@ -0,0 +1,119 @@
+<style>
+    .webuploader-pick {
+        background-color: @primary;
+    }
+
+    .web-uploader .placeholder .flashTip a {
+        color: @primary(-10);
+    }
+
+    .web-uploader .statusBar .upload-progress span.percentage,
+    .web-uploader .filelist li p.upload-progress span {
+        background: @primary(-8);
+    }
+
+    .web-uploader .dnd-area.webuploader-dnd-over {
+        border: 3px dashed #999 !important;
+    }
+    .web-uploader .dnd-area.webuploader-dnd-over .placeholder {
+        border: none;
+    }
+
+</style>
+
+<div class="{{$viewClass['form-group']}} {{ $class }}">
+
+    <label for="{{$column}}" class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <input name="{{ $name }}" class="file-input" type="hidden" {!! $attributes !!}/>
+
+        <div class="web-uploader {{ $fileType }}">
+            <div class="queueList dnd-area" @if(!empty($upimgdemo)) style="width: 220px;float: left;" @endif>
+                <div class="placeholder">
+                    <div class="file-picker"></div>
+                    <p>{{trans('admin.uploader.drag_file')}}</p>
+                </div>
+            </div>
+            {{-- 上传图片示例--}}
+            @include('admin::form.upload-img-demo')
+            <div class="statusBar" style="display:none;">
+                <div class="upload-progress progress progress-bar-primary pull-left">
+                    <div class="progress-bar progress-bar-striped active" style="line-height:18px">0%</div>
+                </div>
+                <div class="info"></div>
+                <div class="btns">
+                    <div class="add-file-button"></div>
+                    @if($showUploadBtn)
+                    &nbsp;
+                    <div class="upload-btn btn btn-primary"><i class="feather icon-upload"></i> &nbsp;{{trans('admin.upload')}}</div>
+                    @endif
+                </div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+    </div>
+</div>
+
+<script require="@webuploader" init="{!! $selector !!}">
+    var uploader,
+        newPage,
+        options = {!! $options !!},
+        events = options.events;
+
+    init();
+
+    function init() {
+        var opts = $.extend({
+            selector: $this,
+            addFileButton: $this.find('.add-file-button'),
+            inputSelector: $this.find('.file-input'),
+        }, options);
+
+        opts.upload = $.extend({
+            pick: {
+                id: $this.find('.file-picker'),
+                name: '_file_',
+                label: '<i class="feather icon-folder"><\/i>&nbsp; {!! trans('admin.uploader.add_new_media') !!}'
+            },
+            dnd: $this.find('.dnd-area'),
+            paste: $this.find('.web-uploader')
+        }, opts);
+
+        uploader = Dcat.Uploader(opts);
+        uploader.build();
+        uploader.preview();
+
+        for (var i = 0; i < events.length; i++) {
+            var evt = events[i];
+            if (evt.event && evt.script) {
+                if (evt.once) {
+                    uploader.uploader.once(evt.event, evt.script.bind(uploader))
+                } else {
+                    uploader.uploader.on(evt.event, evt.script.bind(uploader))
+                }
+            }
+        }
+
+        function resize() {
+            setTimeout(function () {
+                if (! uploader) return;
+
+                uploader.refreshButton();
+                resize();
+
+                if (! newPage) {
+                    newPage = 1;
+                    $(document).one('pjax:complete', function () {
+                        uploader = null;
+                    });
+                }
+            }, 250);
+        }
+        resize();
+    }
+</script>

+ 24 - 0
resources/views/distributor/form/footer.blade.php

@@ -0,0 +1,24 @@
+<div class="box-footer">
+
+    <div class="col-md-{{$width['label']}} d-md-block" style="display: none"></div>
+
+    <div class="col-md-{{$width['field']}}">
+
+        @if(! empty($buttons['submit']))
+            <div class="btn-group pull-right">
+                <button class="btn btn-primary submit"><i class="feather icon-save"></i> {{ trans('admin.submit') }}</button>
+            </div>
+
+            @if($checkboxes)
+                <div class="pull-right d-md-flex" style="margin:10px 15px 0 0;display: none">{!! $checkboxes !!}</div>
+            @endif
+
+        @endif
+
+        @if(! empty($buttons['reset']))
+        <div class="btn-group pull-left">
+            <button type="reset" class="btn btn-white"><i class="feather icon-rotate-ccw"></i> {{ trans('admin.reset') }}</button>
+        </div>
+        @endif
+    </div>
+</div>

+ 86 - 0
resources/views/distributor/form/hasmany.blade.php

@@ -0,0 +1,86 @@
+
+<div class="row" style="margin-top: 10px;">
+    <div class="{{$viewClass['label']}}"><h4 class="pull-right">{!! $label !!}</h4></div>
+    <div class="{{$viewClass['field']}}"></div>
+</div>
+
+<hr class="mt-0">
+
+<div class="has-many-{{$columnClass}}">
+
+    <div class="has-many-{{$columnClass}}-forms">
+
+        @foreach($forms as $pk => $form)
+
+            <div class="has-many-{{$columnClass}}-form fields-group">
+
+                {!! $form->render() !!}
+
+                @if($options['allowDelete'])
+                    <div class="form-group row">
+                        <label class="{{$viewClass['label']}} control-label"></label>
+                        <div class="{{$viewClass['field']}}">
+                            <div class="{{$columnClass}}-remove btn btn-white btn-sm pull-right"><i class="feather icon-trash">&nbsp;</i>{{ trans('admin.remove') }}</div>
+                        </div>
+                    </div>
+                @endif
+                <hr>
+            </div>
+
+        @endforeach
+    </div>
+
+
+    <template class="{{$columnClass}}-tpl">
+        <div class="has-many-{{$columnClass}}-form fields-group">
+
+            {!! $template !!}
+
+            <div class="form-group row">
+                <label class="{{$viewClass['label']}} control-label"></label>
+                <div class="{{$viewClass['field']}}">
+                    <div class="{{$columnClass}}-remove btn btn-white btn-sm pull-right"><i class="feather icon-trash"></i>&nbsp;{{ trans('admin.remove') }}</div>
+                </div>
+            </div>
+            <hr>
+        </div>
+    </template>
+
+    @if($options['allowCreate'])
+        <div class="form-group row">
+            <label class="{{$viewClass['label']}} control-label"></label>
+            <div class="{{$viewClass['field']}}">
+                <div class="{{$columnClass}}-add btn btn-primary btn-outline btn-sm"><i class="feather icon-plus"></i>&nbsp;{{ trans('admin.new') }}</div>
+            </div>
+        </div>
+    @endif
+
+</div>
+
+<script>
+    var nestedIndex = {!! $count !!},
+        container = '.has-many-{{ $columnClass }}',
+        forms = '.has-many-{{ $columnClass  }}-forms';
+
+    function replaceNestedFormIndex(value) {
+        return String(value)
+            .replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex)
+            .replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_PARENT_KEY_NAME }}/g, nestedIndex);
+    }
+
+    $(container).on('click', '.{{$columnClass}}-add', function () {
+        var tpl = $('template.{{ $columnClass }}-tpl');
+
+        nestedIndex++;
+
+        $(forms).append(replaceNestedFormIndex(tpl.html()));
+    });
+
+    $(container).on('click', '.{{$columnClass}}-remove', function () {
+        var $form = $(this).closest('.has-many-{{ $columnClass }}-form');
+
+        $form.hide();
+        $form.find('.{{ Dcat\Admin\Form\NestedForm::REMOVE_FLAG_CLASS }}').val(1);
+        $form.find('[required]').prop('required', false);
+    });
+</script>

+ 104 - 0
resources/views/distributor/form/hasmanytab.blade.php

@@ -0,0 +1,104 @@
+<style>
+    .nav-tabs > li:hover > i{
+        display: inline;
+    }
+    .close-tab {
+        position: absolute;
+        font-size: 10px;
+        top: 20px;
+        right: 0;
+        cursor: pointer;
+        display: none;
+    }
+</style>
+<div class="nav-tabs-custom has-many-{{$columnClass}}">
+    <div class="row header">
+        <div class="{{$viewClass['label']}}"><h4 class="pull-right">{!! $label !!}</h4></div>
+        <div class="{{$viewClass['field']}}" style="margin-bottom: 5px">
+            <div class="add btn btn-outline-primary btn-sm"><i class="feather icon-plus"></i>&nbsp;{{ trans('admin.new') }}</div>
+        </div>
+    </div>
+
+    <hr class="mb-0 mt-0">
+
+    <ul class="nav nav-tabs">
+        @foreach($forms as $pk => $form)
+            <li class="nav-item ">
+                <a href="#{{ $relationName . '_' . $pk }}" class="nav-link @if ($form == reset($forms)) active @endif " data-toggle="tab">
+                    {{ $pk }} <i class="feather icon-alert-circle text-red d-none"></i>
+                </a>
+                <i class="close-tab feather icon-trash text-red"></i>
+            </li>
+        @endforeach
+
+    </ul>
+    
+    <div class="tab-content has-many-{{$columnClass}}-forms">
+
+        @foreach($forms as $pk => $form)
+            <div class="tab-pane fields-group has-many-{{$columnClass}}-form @if ($form == reset($forms)) active @endif" id="{{ $relationName . '_' . $pk }}">
+                {!! $form->render() !!}
+            </div>
+        @endforeach
+    </div>
+
+    <template class="nav-tab-tpl">
+        <li class="new nav-item">
+            <a href="#{{ $relationName . '_new_' . \Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}" class="nav-link" data-toggle="tab">
+                &nbsp;New {{ \Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }} <i class="feather icon-alert-circle text-red d-none"></i>
+            </a>
+            <i class="close-tab feather icon-trash text-red" ></i>
+        </li>
+    </template>
+    <template class="pane-tpl">
+        <div class="tab-pane fields-group new" id="{{ $relationName . '_new_' . Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}">
+            {!! $template !!}
+        </div>
+    </template>
+
+</div>
+
+<script>
+    var container = '.has-many-{{ $columnClass }}';
+    
+    $(container+' > .nav').off('click', 'i.close-tab').on('click', 'i.close-tab', function(){
+        var $navTab = $(this).siblings('a');
+        var $pane = $($navTab.attr('href'));
+        if( $pane.hasClass('new') ){
+            $pane.remove();
+        }else{
+            $pane.removeClass('active').find('.{{ Dcat\Admin\Form\NestedForm::REMOVE_FLAG_CLASS }}').val(1);
+        }
+        if($navTab.closest('li').hasClass('active')){
+            $navTab.closest('li').remove();
+            $(container+' > .nav > li:nth-child(1) > a').click();
+        }else{
+            $navTab.closest('li').remove();
+        }
+    });
+
+    var nestedIndex = {!! $count !!};
+
+    function replaceNestedFormIndex(value) {
+        return String(value).replace(/{{ Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex);
+    }
+
+    $(container+' > .header').off('click', '.add').on('click', '.add', function(){
+        nestedIndex++;
+        var navTabHtml = replaceNestedFormIndex($(container+' > template.nav-tab-tpl').html());
+        var paneHtml = replaceNestedFormIndex($(container+' > template.pane-tpl').html());
+        $(container+' > .nav').append(navTabHtml);
+        $(container+' > .tab-content').append(paneHtml);
+        $(container+' > .nav > li:last-child a').click();
+    });
+
+    if ($('.has-error').length) {
+        $('.has-error').parent('.tab-pane').each(function () {
+            var tabId = '#'+$(this).attr('id');
+            $('li a[href="'+tabId+'"] i').removeClass('d-none');
+        });
+
+        var first = $('.has-error:first').parent().attr('id');
+        $('li a[href="#'+first+'"]').tab('show');
+    }
+</script>

+ 112 - 0
resources/views/distributor/form/hasmanytable.blade.php

@@ -0,0 +1,112 @@
+<style>
+    .table-has-many .input-group{flex-wrap: nowrap!important}
+</style>
+
+<div class="row form-group">
+    <div class="{{$viewClass['label']}} "><label class="control-label pull-right">{!! $label !!}</label></div>
+    <div class="{{$viewClass['field']}}">
+        @include('admin::form.error')
+
+        <span name="{{$column}}"></span> {{-- 用于显示错误信息 --}}
+
+        <div class="has-many-table-{{$columnClass}}" >
+            <table class="table table-has-many has-many-table-{{$columnClass}}">
+                <thead>
+                <tr>
+                    @foreach($headers as $header)
+                        <th>{{ $header }}</th>
+                    @endforeach
+
+                    <th class="hidden"></th>
+
+                    @if($options['allowDelete'])
+                        <th></th>
+                    @endif
+                </tr>
+                </thead>
+                <tbody class="has-many-table-{{$columnClass}}-forms">
+                @foreach($forms as $pk => $form)
+                    <tr class="has-many-table-{{$columnClass}}-form fields-group">
+
+                        <?php $hidden = ''; ?>
+
+                        @foreach($form->fields() as $field)
+
+                            @if (is_a($field, Dcat\Admin\Form\Field\Hidden::class))
+                                <?php $hidden .= $field->render(); ?>
+                                @continue
+                            @endif
+
+                            <td>{!! $field->setLabelClass(['hidden'])->width(12, 0)->render() !!}</td>
+                        @endforeach
+
+                        <td class="hidden">{!! $hidden !!}</td>
+
+                        @if($options['allowDelete'])
+                            <td class="form-group">
+                                <div>
+                                    <div class="remove btn btn-white btn-sm pull-right"><i class="feather icon-trash"></i></div>
+                                </div>
+                            </td>
+                        @endif
+                    </tr>
+                @endforeach
+                </tbody>
+            </table>
+
+            <template class="{{$columnClass}}-tpl">
+                <tr class="has-many-table-{{$columnClass}}-form fields-group">
+
+                    {!! $template !!}
+
+                    <td class="form-group">
+                        <div>
+                            <div class="remove btn btn-white btn-sm pull-right"><i class="feather icon-trash"></i></div>
+                        </div>
+                    </td>
+                </tr>
+            </template>
+
+            @if($options['allowCreate'])
+                <div class="form-group row m-t-10">
+                    <div class="{{$viewClass['field']}}" style="margin-top: 8px">
+                        <div class="add btn btn-primary btn-outline btn-sm"><i class="feather icon-plus"></i>&nbsp;{{ trans('admin.new') }}</div>
+                    </div>
+                </div>
+            @endif
+        </div>
+    </div>
+</div>
+
+{{--<hr style="margin-top: 0px;">--}}
+
+<script>
+(function () {
+    var nestedIndex = {!! $count !!},
+        container = '.has-many-table-{{ $columnClass }}';
+
+    function replaceNestedFormIndex(value) {
+        return String(value).replace(/{{ $parentKey ?: Dcat\Admin\Form\NestedForm::DEFAULT_KEY_NAME }}/g, nestedIndex);
+    }
+
+    $(document).off('click', container+' .add').on('click', container+' .add', function (e) {
+        var $con = $(this).closest(container);
+        var tpl = $con.find('template.{{ $columnClass }}-tpl');
+
+        nestedIndex++;
+
+        $con.find('.has-many-table-{{ $columnClass }}-forms').append(replaceNestedFormIndex(tpl.html()));
+
+        e.preventDefault();
+        return false
+    });
+
+    $(document).off('click', container+' .remove').on('click', container+' .remove', function () {
+        var $form = $(this).closest('.has-many-table-{{ $columnClass }}-form');
+
+        $form.hide();
+        $form.find('[required]').prop('required', false);
+        $form.find('.{{ Dcat\Admin\Form\NestedForm::REMOVE_FLAG_CLASS }}').val(1);
+    });
+})();
+</script>

+ 5 - 0
resources/views/distributor/form/help-block.blade.php

@@ -0,0 +1,5 @@
+@if($help)
+<span class="help-block">
+    <i class="fa {{ \Illuminate\Support\Arr::get($help, 'icon') }}"></i>&nbsp;{!! \Illuminate\Support\Arr::get($help, 'text') !!}
+</span>
+@endif

+ 1 - 0
resources/views/distributor/form/hidden.blade.php

@@ -0,0 +1 @@
+<input type="hidden" name="{{$name}}" value="{{$value}}" class="{{$class}}" {!! $attributes !!} />

+ 10 - 0
resources/views/distributor/form/id.blade.php

@@ -0,0 +1,10 @@
+<div class="{{$viewClass['form-group']}}">
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+        <input type="text" name="{{$name}}" value="{{$value}}" class="form-control" readonly {!! $attributes !!} />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 26 - 0
resources/views/distributor/form/input.blade.php

@@ -0,0 +1,26 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <div class="{{$viewClass['label']}} control-label">
+        <span>{!! $label !!}</span>
+    </div>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="input-group">
+
+            @if ($prepend)
+                <span class="input-group-prepend"><span class="input-group-text bg-white">{!! $prepend !!}</span></span>
+            @endif
+            <input {!! $attributes !!} />
+
+            @if ($append)
+                <span class="input-group-append">{!! $append !!}</span>
+            @endif
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 112 - 0
resources/views/distributor/form/keyvalue.blade.php

@@ -0,0 +1,112 @@
+<style>
+    td .form-group {margin-bottom: 0 !important;}
+</style>
+
+<div class="{{$viewClass['form-group']}} {{ $class }}">
+
+    <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
+
+    <div class="{{$viewClass['field']}}">
+        <span name="{{$name}}"></span>
+        <input name="{{ $name }}[{{ \Dcat\Admin\Form\Field\KeyValue::DEFAULT_FLAG_NAME }}]" type="hidden" />
+
+        <div class="help-block with-errors"></div>
+
+        <table class="table table-hover">
+            <thead>
+            <tr>
+                <th>{!! $keyLabel !!}</th>
+                <th>{!! $valueLabel !!}</th>
+                <th style="width: 85px;"></th>
+            </tr>
+            </thead>
+            <tbody class="kv-table">
+
+            @foreach(($value ?: []) as $k => $v)
+                <tr>
+                    <td>
+                        <div class="form-group">
+                            <div class="col-sm-12">
+                                <div class="help-block with-errors"></div>
+
+                                <input name="{{ $name }}[keys][{{ $loop->index }}]" value="{{ $k }}" class="form-control" required/>
+
+                            </div>
+                        </div>
+                    </td>
+                    <td>
+                        <div class="form-group">
+                            <div class="col-sm-12">
+                                <div class="help-block with-errors"></div>
+                                <input name="{{ $name }}[values][{{ $loop->index }}]" value="{{ $v }}" class="form-control" />
+                            </div>
+                        </div>
+                    </td>
+
+                    <td class="form-group">
+                        <div>
+                            <div class="kv-remove btn btn-white btn-sm pull-right">
+                                <i class="feather icon-trash">&nbsp;</i>
+                            </div>
+                        </div>
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+            <tfoot>
+            <tr>
+                <td></td>
+                <td></td>
+                <td>
+                    <div class="kv-add btn btn-primary btn-outline btn-sm pull-right">
+                        <i class="feather icon-save"></i>&nbsp;{{ __('admin.new') }}
+                    </div>
+                </td>
+            </tr>
+            </tfoot>
+        </table>
+    </div>
+
+    <template>
+        <tr>
+            <td>
+                <div class="form-group  ">
+                    <div class="col-sm-12">
+                        <div class="help-block with-errors"></div>
+                        <input name="{{ $name }}[keys][{key}]" class="form-control" required/>
+                    </div>
+                </div>
+            </td>
+            <td>
+                <div class="form-group  ">
+                    <div class="col-sm-12">
+                        <div class="help-block with-errors"></div>
+                        <input name="{{ $name }}[values][{key}]" class="form-control" />
+                    </div>
+                </div>
+            </td>
+
+            <td class="form-group">
+                <div>
+                    <div class="kv-remove btn btn-white btn-sm pull-right">
+                        <i class="feather icon-trash">&nbsp;</i>
+                    </div>
+                </div>
+            </td>
+        </tr>
+    </template>
+</div>
+
+<script init="{!! $selector !!}">
+    var index = {{ $count }};
+    $this.find('.kv-add').on('click', function () {
+        var tpl = $this.find('template').html().replace('{key}', index).replace('{key}', index);
+        $this.find('tbody.kv-table').append(tpl);
+
+        index++;
+    });
+
+    $this.find('tbody.kv-table').on('click', '.kv-remove', function () {
+        $(this).closest('tr').remove();
+    });
+</script>

+ 23 - 0
resources/views/distributor/form/listbox.blade.php

@@ -0,0 +1,23 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}[]" multiple="multiple" data-placeholder="{{ $placeholder }}" {!! $attributes !!} >
+            @foreach($options as $select => $option)
+                <option value="{{$select}}" {{  in_array($select, (array) $value) ?'selected':'' }}>{{$option}}</option>
+            @endforeach
+        </select>
+        <input type="hidden" name="{{$name}}[]" />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@jquery.bootstrap-duallistbox" init="{!! $selector !!}">
+    $this.bootstrapDualListbox({!! admin_javascript_json($settings) !!});
+</script>

+ 85 - 0
resources/views/distributor/form/listfield.blade.php

@@ -0,0 +1,85 @@
+<style>
+    td .form-group {margin-bottom: 0 !important;}
+</style>
+
+<div class="{{$viewClass['form-group']}} {{$class}}">
+
+    <label class="{{$viewClass['label']}} control-label">{{$label}}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        <div class="help-block with-errors"></div>
+
+        <span name="{{$name}}"></span>
+        <input name="{{ $name }}[values][{{ Dcat\Admin\Form\Field\ListField::DEFAULT_FLAG_NAME }}]" type="hidden" />
+
+        <table class="table table-hover">
+
+            <tbody class="list-table">
+
+            @foreach(($value ?: []) as $k => $v)
+                <tr>
+                    <td>
+                        <div class="form-group">
+                            <div class="col-sm-12">
+                                <input name="{{ $name }}[values][{{ (int) $k }}]" value="{{ $v }}" class="form-control" />
+                                <div class="help-block with-errors"></div>
+                            </div>
+                        </div>
+                    </td>
+
+                    <td style="width: 85px;">
+                        <div class="{{$class}}-remove list-remove btn btn-white btn-sm pull-right">
+                            <i class="feather icon-trash">&nbsp;</i>
+                        </div>
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+            <tfoot>
+            <tr>
+                <td colspan="2">
+                    <div class="list-add btn btn-primary btn-outline btn-sm pull-left">
+                        <i class="feather icon-save"></i>&nbsp;{{ __('admin.new') }}
+                    </div>
+                    <div class="text-center">
+                        @include('admin::form.help-block')
+                    </div>
+                </td>
+            </tr>
+            </tfoot>
+        </table>
+    </div>
+
+    <template>
+        <tr>
+            <td>
+                <div class="form-group">
+                    <div class="col-sm-12">
+                        <input name="{{ $name }}[values][{key}]" class="form-control" />
+                        <div class="help-block with-errors"></div>
+                    </div>
+                </div>
+            </td>
+
+            <td style="width: 85px;">
+                <div class="list-remove btn btn-white btn-sm pull-right">
+                    <i class="feather icon-trash">&nbsp;</i>
+                </div>
+            </td>
+        </tr>
+    </template>
+</div>
+
+<script init="{!! $selector !!}">
+    var index = {{ $count }};
+    $this.find('.list-add').on('click', function () {
+        var tpl = $this.find('template').html().replace('{key}', index);
+        $this.find('tbody.list-table').append(tpl);
+
+        index++;
+    });
+    $this.find('tbody.list-table').on('click', '.list-remove', function () {
+        $(this).closest('tr').remove();
+    });
+</script>

+ 274 - 0
resources/views/distributor/form/map.blade.php

@@ -0,0 +1,274 @@
+<style>
+    .amap-icon img,
+    .amap-marker-content img{
+        width: 25px;
+        height: 34px;
+    }
+</style>
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        @if($type === 'baidu' || $type === 'amap')
+            <div class="row mb-1">
+                <div class="col-md-5 col-md-offset-3">
+                    <div class="input-group">
+                        <input type="text" placeholder="{{ trans('admin.search') }}" class="form-control" id="{{ $searchId }}">
+                        @if($type === 'baidu')
+                            <span class="input-group-btn">
+                                <button type="button" class="btn btn-primary btn-flat"><i class="fa fa-search"></i></button>
+                            </span>
+                        @endif
+                    </div>
+                </div>
+            </div>
+        @endif
+
+        <div class="{{ $class }}">
+            <div class="form-map" style="width: 100%;height: {{ $height }}"></div>
+            <input type="hidden" class="form-lat" name="{{ $name['lat'] }}" value="{{ $value['lat'] ?? null }}" {!! $attributes !!} />
+            <input type="hidden" class="form-lng" name="{{$name['lng']}}" value="{{ $value['lng'] ?? null }}" {!! $attributes !!} />
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+<script init="{!! $selector !!}">
+    var lat = $this.find('.form-lat'),
+        lng = $this.find('.form-lng'),
+        container = $this.find('.form-map'),
+        mapId = "_" + Dcat.helpers.random();
+
+    container.attr('id', mapId);
+
+    @if($type === 'google')
+    function initGoogleMap() {
+        var LatLng = new google.maps.LatLng(lat.val(), lng.val());
+
+        var options = {
+            zoom: 13,
+            center: LatLng,
+            panControl: false,
+            zoomControl: true,
+            scaleControl: true,
+            mapTypeId: google.maps.MapTypeId.ROADMAP
+        }
+
+        var map = new google.maps.Map(container[0], options);
+
+        var marker = new google.maps.Marker({
+            position: LatLng,
+            map: map,
+            title: 'Drag Me!',
+            draggable: true
+        });
+
+        google.maps.event.addListener(marker, 'dragend', function (event) {
+            lat.val(event.latLng.lat());
+            lng.val(event.latLng.lng());
+        });
+    }
+
+    initGoogleMap();
+    @endif
+
+    @if($type === 'tencent')
+    function initTencentMap() {
+        var center = new qq.maps.LatLng(lat.val(), lng.val());
+
+        var map = new qq.maps.Map(container[0], {
+            center: center,
+            zoom: 13
+        });
+
+        var marker = new qq.maps.Marker({
+            position: center,
+            draggable: true,
+            map: map
+        });
+
+        if( ! lat.val() || ! lng.val()) {
+            var citylocation = new qq.maps.CityService({
+                complete : function(result){
+                    map.setCenter(result.detail.latLng);
+                    marker.setPosition(result.detail.latLng);
+                }
+            });
+
+            citylocation.searchLocalCity();
+        }
+
+        qq.maps.event.addListener(map, 'click', function(event) {
+            marker.setPosition(event.latLng);
+        });
+
+        qq.maps.event.addListener(marker, 'position_changed', function(event) {
+            var position = marker.getPosition();
+            lat.val(position.getLat());
+            lng.val(position.getLng());
+        });
+    }
+
+    initTencentMap();
+    @endif
+
+
+    @if($type === 'yandex')
+    function initYandexMap() {
+        ymaps.ready(function(){
+            var myMap = new ymaps.Map(mapId, {
+                center: [lat.val(), lng.val()],
+                zoom: 18
+            });
+
+            var myPlacemark = new ymaps.Placemark([lat.val(), lng.val()], {
+            }, {
+                preset: 'islands#redDotIcon',
+                draggable: true
+            });
+
+            myPlacemark.events.add(['dragend'], function (e) {
+                lat.val(myPlacemark.geometry.getCoordinates()[0]);
+                lng.val(myPlacemark.geometry.getCoordinates()[1]);
+            });
+
+            myMap.geoObjects.add(myPlacemark);
+        });
+    }
+
+    initYandexMap();
+    @endif
+
+    @if($type === 'baidu')
+    function initBaiduMap() {
+        var map = new BMap.Map(mapId);
+        var point = new BMap.Point(lng.val(), lat.val());
+        map.centerAndZoom(point, 15);
+        map.enableScrollWheelZoom(true);
+
+        var marker = new BMap.Marker(point);
+        map.addOverlay(marker);
+        marker.enableDragging();
+
+        if (! lat.val() || ! lng.val()) {
+            var geolocation = new BMap.Geolocation();
+            geolocation.getCurrentPosition(function(e){
+                if (this.getStatus() == BMAP_STATUS_SUCCESS) {
+                    map.panTo(e.point);
+                    marker.setPosition(e.point);
+
+                    lat.val(e.point.lat);
+                    lng.val(e.point.lng);
+
+                } else {
+                    console.log('failed'+this.getStatus());
+                }
+            },{enableHighAccuracy: true})
+        }
+
+        map.addEventListener("click", function(e) {
+            marker.setPosition(e.point);
+            lat.val(e.point.lat);
+            lng.val(e.point.lng);
+        });
+
+        marker.addEventListener("dragend", function(e) {
+            lat.val(e.point.lat);
+            lng.val(e.point.lng);
+        });
+        var ac = new BMap.Autocomplete(
+            {"input" : "{{ $searchId }}"
+                ,"location" : map
+            });
+        var address;
+        ac.addEventListener("onconfirm", function(e) {    //鼠标点击下拉列表后的事件
+            var _value = e.item.value;
+            address = _value.province +  _value.city +  _value.district +  _value.street +  _value.business;
+            setPlace();
+        });
+        function setPlace() {
+            function myFun() {
+                var pp = local.getResults().getPoi(0).point;
+                map.centerAndZoom(pp, 15);
+                marker.setPosition(pp);
+                lat.val(pp.lat);
+                lng.val(pp.lng);
+            }
+            var local = new BMap.LocalSearch(map, {
+                onSearchComplete: myFun
+            });
+            local.search(address);
+        }
+    }
+
+    initBaiduMap();
+    @endif
+    @if($type === 'amap')
+    function initAmap(){
+        var map = new AMap.Map(container[0], {
+            resizeEnable: true,
+            center: lng.val() && lat.val() ? [lng.val(), lat.val()] : null,
+            zoom: 14
+        });
+        var marker = new AMap.Marker({
+            position: new AMap.LngLat(lng.val(), lat.val()),
+            draggable: true,
+            map:map,
+            icon:'//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
+            zoom:15
+        });
+        if (!lng.val() || !lat.val()){
+            var geolocation = new AMap.Geolocation({
+                enableHighAccuracy: true,
+                zoomToAccuracy: true,
+                buttonPosition: 'RB'
+            })
+            geolocation.getCurrentPosition(function (status,result){
+                if (status === 'complete'){
+                    var point = new AMap.LngLat(result.position.lng, result.position.lat);
+                    map.setCenter(point);
+                    map.setZoom(15);
+                    marker.setPosition(point)
+                    lat.val(result.position.lat);
+                    lng.val(result.position.lng);
+                }
+            })
+        }
+        //输入提示
+        var auto = new AMap.Autocomplete({
+            input: "{{$searchId}}"
+        });
+        var placeSearch = new AMap.PlaceSearch({
+            map: map
+        });
+        AMap.event.addListener(auto, "select", function (e){
+            placeSearch.setCity(e.poi.adcode);
+            placeSearch.search(e.poi.name);
+        });
+        AMap.event.addListener(placeSearch, "markerClick", function (e){
+            let point = new AMap.LngLat(e.data.location.lng, e.data.location.lat);
+            marker.setPosition(point)
+            lat.val(e.data.location.lat);
+            lng.val(e.data.location.lng);
+        });
+        marker.on('dragend',function (e){
+            lat.val(e.lnglat.lat);
+            lng.val(e.lnglat.lng);
+        });
+        map.on('click',function (e){
+            if (e.type === 'click'){
+                let point = new AMap.LngLat(e.lnglat.lng, e.lnglat.lat);
+                marker.setPosition(point)
+                lat.val(e.lnglat.lat);
+                lng.val(e.lnglat.lng);
+            }
+        })
+    }
+    initAmap();
+    @endif
+</script>

+ 33 - 0
resources/views/distributor/form/markdown.blade.php

@@ -0,0 +1,33 @@
+<style>
+    .editormd-fullscreen {z-index: 99999999;}
+</style>
+
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="{{$class}}" {!! $attributes !!}>
+            <textarea class="d-none" name="{{$name}}" placeholder="{{ $placeholder }}">{!! $value !!}</textarea>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script first>
+    var ele = window.Element;
+    Dcat.eMatches = ele.prototype.matches ||
+        ele.prototype.msMatchesSelector ||
+        ele.prototype.webkitMatchesSelector;
+</script>
+
+<script require="@editor-md-form" init="{!! $selector !!}">
+    editormd(id, {!! $options !!});
+
+    Element.prototype.matches = Dcat.eMatches;
+</script>

+ 23 - 0
resources/views/distributor/form/multipleselect.blade.php

@@ -0,0 +1,23 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <div  class="{{$viewClass['label']}} control-label">
+        <span>{!! $label !!}</span>
+    </div>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <select class="form-control {{$class}}" style="width: 100%!important;" name="{{$name}}[]" multiple="multiple" data-placeholder="{{ $placeholder }}" {!! $attributes !!} >
+            @foreach($options as $select => $option)
+                <option value="{{ $select }}" {{  in_array($select, (array) $value) ?'selected':'' }}>{{$option}}</option>
+            @endforeach
+        </select>
+        <input type="hidden" name="{{$name}}[]" />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+@include('admin::form.select-script')

+ 34 - 0
resources/views/distributor/form/number.blade.php

@@ -0,0 +1,34 @@
+<style>
+    .number-group .input-group{flex-wrap: nowrap}
+</style>
+
+<div class="{{$viewClass['form-group']}}">
+
+    <div  class="{{$viewClass['label']}} control-label">
+        <span>{!! $label !!}</span>
+    </div>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="input-group number-group">
+
+            @if ($prepend)
+                <span class="input-group-prepend"><span class="input-group-text bg-white">{!! $prepend !!}</span></span>
+            @endif
+            <input {!! $attributes !!} />
+
+            @if ($append)
+                <span class="input-group-append">{!! $append !!}</span>
+            @endif
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@number-input" init="{!! $selector !!}">
+    $this.bootstrapNumber({!! admin_javascript_json($options) !!});
+</script>

+ 39 - 0
resources/views/distributor/form/radio.blade.php

@@ -0,0 +1,39 @@
+<div class="{{$viewClass['form-group']}}" >
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <input type="hidden" name="{{$name}}">
+
+        {!! $radio !!}
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+@if(! empty($loads))
+<script once>
+    var selector = '{!! $selector !!}',
+        fields = '{!! $loads['fields'] !!}'.split('^'),
+        urls = '{!! $loads['urls'] !!}'.split('^');
+
+    $(document).off('change', selector);
+    $(document).on('change', selector, function () {
+        var values = this.value;
+
+        Dcat.helpers.loadFields(this, {
+            group: '.fields-group',
+            urls: urls,
+            fields: fields,
+            textField: "{{ $loads['textField'] }}",
+            idField: "{{ $loads['idField'] }}",
+            values: values,
+        });
+    });
+    $(selector+':checked').trigger('change')
+</script>
+@endif

+ 32 - 0
resources/views/distributor/form/range.blade.php

@@ -0,0 +1,32 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="row" style="max-width: 603px">
+            <div class="col-lg-6">
+                <div class="input-group">
+                     <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-edit-2"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['start']}}" value="{{ $value['start'] ?? null }}" class="form-control {{$class['start']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+
+            <div class="col-lg-6">
+                <div class="input-group">
+                     <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="feather icon-edit-2"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['end']}}" value="{{ $value['end'] ?? null }}" class="form-control {{$class['end']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 17 - 0
resources/views/distributor/form/rate.blade.php

@@ -0,0 +1,17 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="input-group" style="width: 150px">
+            <input type="text" name="{{$name}}" value="{{ $value }}" class="form-control {{ $class }}" placeholder="0" style="text-align:right;" {!! $attributes !!} />
+            <span class="input-group-addon">%</span>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 7 - 0
resources/views/distributor/form/row.blade.php

@@ -0,0 +1,7 @@
+<div class="row" style="margin-bottom: 8px">
+    @foreach($fields as $field)
+    <div class="col-md-{{ $field['width'] }}">
+        {!! $field['element']->render() !!}
+    </div>
+    @endforeach
+</div>

+ 31 - 0
resources/views/distributor/form/select-script.blade.php

@@ -0,0 +1,31 @@
+
+@include('admin::scripts.select')
+
+<script require="@select2?lang={{ config('app.locale') === 'en' ? '' : str_replace('_', '-', config('app.locale')) }}" init="{!! $selector !!}">
+    var configs = {!! admin_javascript_json($configs) !!};
+
+    @yield('admin.select-ajax')
+
+    @if(isset($remoteOptions))
+    $.ajax({!! admin_javascript_json($remoteOptions) !!}).done(function(data) {
+        configs.data = data;
+
+        $this.each(function (_, select) {
+            select = $(select);
+
+            select.select2(configs);
+
+            var value = select.data('value') + '';
+
+            if (value) {
+                select.val(value.split(',')).trigger("change")
+            }
+        });
+    });
+    @else
+    $this.select2(configs);
+    @endif
+
+    {!! $cascadeScript !!}
+</script>
+

+ 35 - 0
resources/views/distributor/form/select.blade.php

@@ -0,0 +1,35 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <div  class="{{ $viewClass['label'] }} control-label">
+        <span>{!! $label !!}</span>
+    </div>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <input type="hidden" name="{{$name}}"/>
+
+        <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}" {!! $attributes !!} >
+            <option value=""></option>
+            @if($groups)
+                @foreach($groups as $group)
+                    <optgroup label="{{ $group['label'] }}">
+                        @foreach($group['options'] as $select => $option)
+                            <option value="{{$select}}" {{ $select == $value ?'selected':'' }}>{{$option}}</option>
+                        @endforeach
+                    </optgroup>
+                @endforeach
+             @else
+                @foreach($options as $select => $option)
+                    <option value="{{$select}}" {{ Dcat\Admin\Support\Helper::equal($select, $value) ?'selected':'' }}>{{$option}}</option>
+                @endforeach
+            @endif
+        </select>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+@include('admin::form.select-script')

+ 58 - 0
resources/views/distributor/form/selecttable.blade.php

@@ -0,0 +1,58 @@
+<div class="{{$viewClass['form-group']}}">
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+    <div class="{{$viewClass['field']}} select-resource">
+        @include('admin::form.error')
+
+        <div class="input-group">
+            <div {!! $attributes !!}>
+                <span class="default-text" style="opacity:0.75">{{ $placeholder }}</span>
+                <span class="option d-none"></span>
+
+                @if(! $disabled)
+                    <input name="{{ $name }}" type="hidden" value="{{ implode(',', Dcat\Admin\Support\Helper::array($value)) }}" />
+                @endif
+            </div>
+
+            <div class="input-group-append">
+                {!! $dialog !!}
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@select-table" init="{!! $selector !!}">
+    var dialogId = $this.parent().find('{!! $dialogSelector !!}').attr('id');
+    var $input = $(this).find('input');
+
+    Dcat.grid.SelectTable({
+        dialog: '[data-id="' + dialogId + '"]',
+        container: $this,
+        input: $input,
+        @if(isset($max))
+        multiple: true,
+        max: {{ $max }},
+        @endif
+        values: {!! json_encode($options) !!},
+    });
+
+    @if(! empty($loads))
+    var fields = '{!! $loads['fields'] !!}'.split('^');
+    var urls = '{!! $loads['urls'] !!}'.split('^');
+
+    $input.on('change', function () {
+        var values = this.value;
+
+        Dcat.helpers.loadFields(this, {
+            group: '.fields-group',
+            urls: urls,
+            fields: fields,
+            textField: "{{ $loads['textField'] }}",
+            idField: "{{ $loads['idField'] }}",
+            values: values,
+        });
+    }).trigger('change');
+    @endif
+</script>

+ 20 - 0
resources/views/distributor/form/slider.blade.php

@@ -0,0 +1,20 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <input type="text" class="{{$class}}" name="{{$name}}" data-from="{{ $value }}" {!! $attributes !!} />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@ionslider" init="{!! $selector !!}">
+    setTimeout(function () {
+        $this.ionRangeSlider({!! admin_javascript_json($options) !!})
+    }, 400);
+</script>

+ 46 - 0
resources/views/distributor/form/steps/completion-page.blade.php

@@ -0,0 +1,46 @@
+<style>
+    .dcat-done-step {
+        max-width: 560px;
+        margin: 0 auto;
+        padding: 24px 0 8px;
+    }
+    .dcat-done-step .st-icon {
+        color: {{ Dcat\Admin\Admin::color()->success() }};
+        font-size: 72px;
+        text-align:center;
+    }
+    .dcat-done-step .st-content {
+        text-align:center;
+    }
+    .dcat-done-step .st-title {
+        font-size: 24px;
+    }
+    .dcat-done-step .st-desc {
+        color: rgba(0,0,0,.5);
+        font-size: 14px;
+        line-height: 1.6;
+    }
+    .dcat-done-step .st-btn {
+        margin: 30px 0 10px;
+    }
+</style>
+<div style="margin: 0 auto">
+    <div class="st-icon">
+        <svg viewBox="64 64 896 896" focusable="false" class="" data-icon="check-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path></svg>
+    </div>
+
+    <div class="st-content">
+        <div class="st-title">
+            {{ $title }}
+        </div>
+        <div class="st-desc">
+            {{ $description }}
+        </div>
+
+        <div class="st-btn">
+            <a class="btn btn-success" href="{{ $createUrl }}" >{{ trans('admin.continue_creating') }}</a>
+            &nbsp;
+            <a class="btn btn-white" href="{{ $backUrl }}"><i class="fa fa-long-arrow-left"></i> {{ trans('admin.back') }}</a>
+        </div>
+    </div>
+</div>

+ 10 - 0
resources/views/distributor/form/steps/form.blade.php

@@ -0,0 +1,10 @@
+{!! $start !!}
+<div class="box-body fields-group">
+
+    @foreach($fields as $field)
+        {!! $field->render() !!}
+    @endforeach
+
+</div>
+
+{!! $end !!}

+ 310 - 0
resources/views/distributor/form/steps/steps.blade.php

@@ -0,0 +1,310 @@
+<style>
+    .dcat-step .dcat-step-item:not(.active) > .dcat-step-item-container[role=button]:hover .dcat-step-icons,
+    .done > .dcat-step-item-container > .dcat-step-line:after,
+    .done .dcat-step-icons,
+    .active .dcat-step-icons {
+        border-color: @primary
+    }
+
+    .dcat-step .dcat-step-item:not(.active) > .dcat-step-item-container[role=button]:hover .dcat-step-icons .dcat-step-icon,
+    .dcat-step .dcat-step-item:not(.active) > .dcat-step-item-container[role=button]:hover .dcat-step-desc .dcat-step .dcat-step-item:not(.active) > .dcat-step-item-container[role=button]:hover .dcat-step-title,
+    .active .dcat-step-icons > .dcat-step-icon {
+        color: #fff
+    }
+
+    .done .dcat-step-icons > .dcat-step-icon {
+        color: @primary
+    }
+
+    .done > .dcat-step-item-container > .dcat-step-content > .dcat-step-title:after,
+    .done .dcat-step-icons > .dcat-step-icon .dcat-step-icon-dot,
+    .active .dcat-step-icons,
+    .active .dcat-step-icons > .dcat-step-icon .dcat-step-icon-dot {
+        background-color: @primary
+    }
+</style>
+
+@if($showHeader)
+    <div class="box-header with-border">
+        <h3 class="box-title" style="line-height:30px">{!! $form->title() !!}</h3>
+        <div class="pull-right">{!! $form->renderTools() !!}</div>
+    </div>
+@endif
+
+<div class="box-body">
+    @if($steps->count())
+        <div class="fields-group dcat-step-box" style="padding: {{ $steps->getOption('padding') }};max-width: {{ $steps->getOption('width') }}">
+
+            <ul class="dcat-step-horizontal dcat-step-label-horizontal dcat-step ">
+                @foreach($steps->all() as $step)
+                    <li class="dcat-step-item">
+                        <a href="#{{ $step->getElementId() }}" class="dcat-step-item-container">
+                            <div class="dcat-step-line"></div>
+                            <div class="dcat-step-icons">
+                                <span class="dcat-step-icon" data-index="{{ $step->index() }}">{{ $step->index() + 1 }}</span>
+                            </div>
+                            <div class="dcat-step-content">
+                                <div class="dcat-step-title">{!! $step->title() !!}</div>
+                                <div class="dcat-step-desc"> {{ $step->description() }} </div>
+                            </div>
+                        </a>
+                    </li>
+                @endforeach
+
+                <li class="dcat-step-item">
+                    <a href="#{{ $steps->done()->getElementId() }}" class="dcat-step-item-container">
+                        <div class="dcat-step-line"></div>
+                        <div class="dcat-step-icons">
+                            <span class="dcat-step-icon" data-index="{{ $steps->count() }}"> {{ $steps->count() + 1 }} </span>
+                        </div>
+                        <div class="dcat-step-content">
+                            <div class="dcat-step-title">{{ $steps->done()->title() }}</div>
+                            <div class="dcat-step-desc"></div>
+                        </div>
+                    </a>
+                </li>
+            </ul>
+            <div class="dcat-step-form">
+                {!! $steps->build() !!}
+
+                <div id="{{ $steps->done()->getElementId() }}" class="dcat-done-step" style="display: none;">
+                </div>
+            </div>
+        </div>
+    @endif
+</div>
+
+<input type="hidden" class="current-step-input" name="{{ Dcat\Admin\Form\Steps\Builder::CURRENT_VALIDATION_STEP }}" />
+<input type="hidden" class="all-steps-input" name="{{ Dcat\Admin\Form\Steps\Builder::ALL_STEPS }}" />
+
+@php
+    $lastStep = $step;
+@endphp
+
+<script>
+Dcat.ready(function () {
+    var form = $('#{{ $form->getElementId() }}'),
+        box = form.find('.dcat-step-box'),
+        stepInput = form.find('.current-step-input'),
+        allStepInput = form.find('.all-steps-input'),
+        smartWizard,
+        isSubmitting;
+
+    var submitBtn = $('<button style="margin-left: 10px"></button>')
+        .text('{{ trans('admin.submit') }}')
+        .addClass('btn btn-primary step-submit-btn disabled d-none')
+        .on('click', function(){
+            var $t = $(this);
+
+            if ($t.hasClass('disabled') || isSubmitting) {
+                return false;
+            }
+
+            form.validator('validate');
+            if (form.find('.has-error').length > 0) {
+                return false;
+            }
+
+            allStepInput.val("1");
+            stepInput.val("");
+            $t.buttonLoading().removeClass('waves-effect');
+            isSubmitting = 1;
+
+            // 提交完整表单
+            submit(function (state, data) {
+                $t.buttonLoading(false);
+                isSubmitting = 0;
+                
+                if (typeof data.status !== 'undefined' && ! data.status) {
+                    return Dcat.handleJsonResponse(data)
+                }
+
+                if (state) {
+                    if (data) {
+                        form.find('.dcat-done-step').html(data);
+                    }
+
+                    smartWizard.next();
+
+                    toggleBtn();
+                }
+            });
+
+            return false;
+
+        });
+
+    smartWizard = box.smartWizard({
+        selected: {{ $steps->getOption('selected') }},
+        transitionEffect: 'fade',
+        useURLhash: false,
+        keyNavigation: false,
+        showStepURLhash: false,
+        autoAdjustHeight: false,
+        lang: {
+            next: '{!! trans('admin.next_step') !!}',
+            previous: '{!! trans('admin.prev_step') !!}'
+        },
+        toolbarSettings: {
+            toolbarPosition: 'bottom',
+            toolbarExtraButtons: [submitBtn,],
+            toolbarButtonPosition: 'left'
+        },
+        anchorSettings: {
+            removeDoneStepOnNavigateBack: true,
+            enableAnchorOnDoneStep: false,
+        },
+    }).on('leaveStep', function (e, tab, idx, direction) {
+                @if ($leaving = $steps->getOption('leaving'))
+
+        var callbacks = [];
+
+        @foreach($leaving as $fun)
+        callbacks.push({!! $fun !!});
+        @endforeach
+
+            return callListeners(callbacks, buildArgs(e, tab, idx, direction));
+        @endif
+
+    }).on('showStep', function (e, tab, idx, direction) {
+                @if ($shown = $steps->getOption('shown'))
+
+        var callbacks = [];
+
+        @foreach($shown as $fun)
+        callbacks.push({!! $fun !!});
+        @endforeach
+
+            return callListeners(callbacks, buildArgs(e, tab, idx, direction));
+        @endif
+    });
+
+    @if ($steps->getOption('leaving') || $steps->getOption('shown'))
+
+    // 执行回调函数
+    function callListeners(func, args) {
+        for (var i in func) {
+            if (func[i](args) === false) {
+                return false;
+            }
+        }
+    }
+
+    // 获取步骤表单
+    function getForm(idx) {
+        return box.find('.dcat-step-form [data-toggle="validator"]').eq(idx);
+    }
+
+    // 构建参数
+    function buildArgs(e, tab, idx, direction) {
+        return {
+            event: e,
+            tab: tab,
+            index: idx,
+            direction: direction,
+            form: getForm(idx),
+            getFrom: function (idx) {
+                return getForm(idx)
+            },
+            formArray: getForm(idx).formToArray(),
+            getFormArray: function (idx) {
+                return getForm(idx).formToArray();
+            }
+        };
+    }
+    @endif
+
+        smartWizard = smartWizard.data('smartWizard');
+
+    // 上一步
+    var prev = box.find('.sw-btn-prev').click(function (e) {
+        e.preventDefault();
+        if (smartWizard.steps.index(this) !== smartWizard.current_index) {
+            smartWizard.prev();
+        }
+
+        toggleBtn();
+    });
+
+    // 下一步
+    var next = box.find('.sw-btn-next').click(function (e) {
+        e.preventDefault();
+
+        if ($(this).hasClass('disabled') || isSubmitting) {
+            return false;
+        }
+
+        var FormStep = form.find('.sw-container [data-toggle="validator"]').eq(smartWizard.current_index);
+
+        FormStep.validator('validate');
+        if (FormStep.find('.has-error').length > 0) {
+            return false;
+        }
+
+        var self = this;
+        $(self).buttonLoading().removeClass('waves-effect');
+        isSubmitting = 1;
+
+        // 发送表单到服务器进行验证
+        stepInput.val(smartWizard.current_index);
+        submit(function (state) {
+            $(self).buttonLoading(false);
+            isSubmitting = 0;
+
+            if (state) {
+                // 表单验证成功
+                if (smartWizard.steps.index(self) !== smartWizard.current_index) {
+                    smartWizard.next();
+                }
+
+                toggleBtn();
+            }
+
+        });
+    });
+
+    // 提交表单
+    function submit(after) {
+        Dcat.Form({
+            form: form,
+            after: function (state, b, c, d) {
+                after(state, b, c, d);
+
+                if (state) {
+                    return false;
+                }
+            }
+        });
+    }
+
+    // 按钮显示隐藏切换
+    function toggleBtn() {
+        var last = {{ $lastStep->index() }},
+            sbm = box.find('.step-submit-btn');
+
+        if (smartWizard.current_index == last) {
+            sbm.removeClass('disabled d-none');
+            next.hide();
+            prev.show();
+        } else {
+            sbm.addClass('disabled d-none');
+            if (smartWizard.current_index !== 0) {
+                prev.show();
+            } else {
+                prev.hide();
+            }
+
+            if (smartWizard.current_index != (last + 1)) {
+                next.show()
+            }
+        }
+
+        if (smartWizard.current_index == (last + 1)) {
+            box.find('.sw-btn-group').remove()
+        }
+    }
+
+    toggleBtn();
+});
+</script>
+

+ 22 - 0
resources/views/distributor/form/switchfield.blade.php

@@ -0,0 +1,22 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+        <input name="{{$name}}" type="hidden" value="0" />
+        <input type="checkbox" name="{{$name}}" class="{{ $class }}" {{ $value == 1 ? 'checked' : '' }} {!! $attributes !!} />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@switchery" init="{!! $selector !!}">
+    $this.parent().find('.switchery').remove();
+
+    $this.each(function() {
+        new Switchery($(this)[0], $(this).data())
+    })
+</script>

+ 33 - 0
resources/views/distributor/form/tab.blade.php

@@ -0,0 +1,33 @@
+<div>
+    <ul class="nav nav-tabs pl-1" style="margin-top: -1rem">
+        @foreach($tabObj->getTabs() as $tab)
+            <li class="nav-item">
+                <a class="nav-link {{ $tab['active'] ? 'active' : '' }}" href="#{{ $tab['id'] }}" data-toggle="tab">
+                    {!! $tab['title'] !!} &nbsp;<i class="feather icon-alert-circle has-tab-error text-danger d-none"></i>
+                </a>
+            </li>
+        @endforeach
+    </ul>
+    <div class="tab-content fields-group mt-2 pt-1 pb-1">
+        @foreach($tabObj->getTabs() as $tab)
+            <div class="tab-pane {{ $tab['active'] ? 'active' : '' }}" id="{{ $tab['id'] }}">
+                @if($tab['layout']->hasColumns())
+                    {!! $tab['layout']->build() !!}
+                @else
+                    @if($tabObj->hasRows)
+                    <div class="ml-2 mb-2" style="margin-top: -1rem">
+                        @foreach($tab['fields'] as $field)
+                            {!! $field->render() !!}
+                        @endforeach
+                    </div>
+                    @else
+                        @foreach($tab['fields'] as $field)
+                            {!! $field->render() !!}
+                        @endforeach
+                    @endif
+                @endif
+            </div>
+        @endforeach
+
+    </div>
+</div>

+ 71 - 0
resources/views/distributor/form/tags.blade.php

@@ -0,0 +1,71 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}[]" multiple="multiple" data-placeholder="{{ $placeholder }}" {!! $attributes !!} >
+            @foreach($options as $key => $option)
+                <option value="{{ $keyAsValue ? $key : $option}}" {{ in_array($option, $value) ? 'selected' : '' }}>{{$option}}</option>
+            @endforeach
+        </select>
+        <input type="hidden" name="{{$name}}[]" />
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script init="{!! $selector !!}" require="@select2?lang={{ config('app.locale') === 'en' ? '' : str_replace('_', '-', config('app.locale')) }}">
+    var options = {
+        tags: true,
+        createTag: function(params) {
+            if (/[,;,; ]/.test(params.term)) {
+                var str = params.term.trim().replace(/[,;,;]*$/, '');
+                return { id: str, text: str }
+            } else {
+                return null;
+            }
+        }
+    };
+
+    @if(isset($ajax))
+    options = $.extend(options, {
+        ajax: {
+            url: "{!! $ajax['url'] !!}",
+            dataType: 'json',
+            delay: 250,
+            cache: true,
+            data: function (params) {
+                return {
+                    q: params.term,
+                    page: params.page
+                };
+            },
+            processResults: function (data, params) {
+                params.page = params.page || 1;
+
+                return {
+                    results: $.map(data.data, function (d) {
+                        d.id = d.{{ $ajax['idField'] }};
+                        d.text = d.{{ $ajax['textField'] }};
+                        return d;
+                    }),
+                    pagination: {
+                        more: data.next_page_url
+                    }
+                };
+            },
+        },
+        escapeMarkup: function (markup) {
+            return markup;
+        },
+    });
+    @endif
+
+    $this.select2(options);
+</script>
+
+

+ 14 - 0
resources/views/distributor/form/textarea.blade.php

@@ -0,0 +1,14 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <textarea name="{{$name}}" class="form-control {{$class}}" rows="{{ $rows }}" placeholder="{{ $placeholder }}" {!! $attributes !!} >{{ $value }}</textarea>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>

+ 47 - 0
resources/views/distributor/form/timerange.blade.php

@@ -0,0 +1,47 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}}">
+
+        @include('admin::form.error')
+
+        <div class="row" style="max-width: 603px">
+            <div class="col-lg-6">
+                <div class="input-group">
+                    <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="fa fa-clock-o fa-fw"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['start']}}" value="{{ $value['start'] ?? null }}" class="form-control {{$class['start']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+
+            <div class="col-lg-6">
+                <div class="input-group">
+                    <span class="input-group-prepend">
+                        <span class="input-group-text bg-white"><i class="fa fa-clock-o fa-fw"></i></span>
+                    </span>
+                    <input autocomplete="off" type="text" name="{{$name['end']}}" value="{{ $value['end'] ?? null }}" class="form-control {{$class['end']}}" style="width: 150px" {!! $attributes !!} />
+                </div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@moment,@bootstrap-datetimepicker" init="{!! $selector['start'] !!}">
+    var options = {!! admin_javascript_json($options) !!};
+    var $end = $('{!! $selector['end'] !!}');
+
+    $this.datetimepicker(options);
+    $end.datetimepicker($.extend(options, {useCurrent: false}));
+    $this.on("dp.change", function (e) {
+        $end.data("DateTimePicker").minDate(e.date);
+    });
+    $end.on("dp.change", function (e) {
+        $this.data("DateTimePicker").maxDate(e.date);
+    });
+</script>
+

+ 57 - 0
resources/views/distributor/form/tree.blade.php

@@ -0,0 +1,57 @@
+<div class="{{$viewClass['form-group']}}">
+
+    <label class="{{$viewClass['label']}} control-label">{!! $label !!}</label>
+
+    <div class="{{$viewClass['field']}} {{ $class }}">
+
+        @include('admin::form.error')
+
+        <div class="input-group" style="width:100%">
+            <input {{$disabled}} type="hidden" class="hidden-input" name="{{$name}}" />
+
+            <div class="jstree-wrapper">
+                <div class="d-flex">
+                    {!! $checkboxes !!}
+                </div>
+                <div class="da-tree" style="margin-top:10px"></div>
+            </div>
+        </div>
+
+        @include('admin::form.help-block')
+
+    </div>
+</div>
+
+<script require="@jstree" init="{!! $selector !!}">
+    var $tree = $this.find('.jstree-wrapper .da-tree'),
+        $input = $this.find('.hidden-input'),
+        opts = {!! admin_javascript_json($options) !!},
+        parents = {!! json_encode($parents) !!};
+
+    opts.core = opts.core || {};
+    opts.core.data = {!! json_encode($nodes) !!};
+
+    $this.find('input[value=1]').on("click", function () {
+        $(this).parents('.jstree-wrapper').find('.da-tree').jstree($(this).prop("checked") ? "check_all" : "uncheck_all");
+    });
+    $this.find('input[value=2]').on("click", function () {
+        $(this).parents('.jstree-wrapper').find('.da-tree').jstree($(this).prop("checked") ? "open_all" : "close_all");
+    });
+
+    $tree.on("changed.jstree", function (e, data) {
+        var i, selected = [];
+
+        $input.val('');
+
+        for (i in data.selected) {
+            if (Dcat.helpers.inObject(parents, data.selected[i])) { // 过滤父节点
+                continue;
+            }
+            selected.push(data.selected[i]);
+        }
+
+        selected.length && $input.val(selected.join(','));
+    }).on("loaded.jstree", function () {
+        @if($expand) $(this).jstree('open_all'); @endif
+    }).jstree(opts);
+</script>

+ 11 - 0
resources/views/distributor/form/upload-img-demo.blade.php

@@ -0,0 +1,11 @@
+@if(!empty($upimgdemo))
+    <div class="upload-img-demo">
+        <div class="form-upload-img-demo">
+            <div class="el-image" >
+              <img src="{{$upimgdemo}}" data-action='preview-img'  class="preview-img spotlight el-image__inner el-image__preview">
+            </div>
+            <div class="form-upload-img-demo-wrap" > 示例 </div>
+        </div>
+    </div>
+    <div style="clear: both;"></div>
+@endif

+ 189 - 0
resources/views/distributor/grid/async-fixed-table.blade.php

@@ -0,0 +1,189 @@
+@if($grid->isAsyncRequest())
+    {!! $grid->renderHeader() !!}
+
+    <div class="table-responsive table-wrapper {{ $grid->option('table_collapse') ? 'table-collapse' : '' }}">
+        <div class="tables-container">
+            <div class="table-wrap table-main" data-height="{{ $tableHeight }}">
+                <table class="custom-data-table async-table {{ $grid->formatTableClass() }}" id="{{ $tableId }}">
+                    <thead>
+                    @if ($headers = $grid->getVisibleComplexHeaders())
+                        <tr>
+                            @foreach($headers as $header)
+                                {!! $header->render() !!}
+                            @endforeach
+                        </tr>
+                    @endif
+                    <tr>
+                        @foreach($grid->getVisibleColumns() as $column)
+                            <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                        @endforeach
+                    </tr>
+                    </thead>
+
+                    @if ($grid->hasQuickCreate())
+                        {!! $grid->renderQuickCreate() !!}
+                    @endif
+
+                    <tbody>
+                    @foreach($grid->rows() as $row)
+                        <tr {!! $row->rowAttributes() !!}>
+                            @foreach($grid->getVisibleColumnNames() as $name)
+                                <td {!! $row->columnAttributes($name) !!}>
+                                    {!! $row->column($name) !!}
+                                </td>
+                            @endforeach
+                        </tr>
+                    @endforeach
+                    @if ($grid->rows()->isEmpty())
+                        <tr>
+                            <td colspan="{!! count($grid->getVisibleColumnNames()) !!}">
+                                <div style="margin:5px 0 0 10px;"><span class="help-block" style="margin-bottom:0"><i class="feather icon-alert-circle"></i>&nbsp;{{ trans('admin.no_data') }}</span></div>
+                            </td>
+                        </tr>
+                    @endif
+                    </tbody>
+                </table>
+            </div>
+
+            @if ($grid->leftVisibleColumns()->isNotEmpty() || $grid->leftVisibleComplexColumns()->isNotEmpty())
+                <div class="table-wrap table-fixed table-fixed-left" data-height="{{ $tableHeight }}">
+                    <table class="custom-data-table  {{ $grid->formatTableClass() }} ">
+                        <thead>
+
+                        @if ($grid->getVisibleComplexHeaders())
+                            <tr>
+                                @foreach($grid->leftVisibleComplexColumns() as $header)
+                                    {!! $header->render() !!}
+                                @endforeach
+                            </tr>
+                            <tr>
+                                @foreach($grid->leftVisibleComplexColumns() as $header)
+                                    @if ($header->getColumnNames()->count() > 1)
+                                        @foreach($header->columns() as $column)
+                                            <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                        @endforeach
+                                    @endif
+                                @endforeach
+                            </tr>
+                        @else
+                            <tr>
+                                @foreach($grid->leftVisibleColumns() as $column)
+                                    <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                @endforeach
+                            </tr>
+                        @endif
+                        </thead>
+                        <tbody>
+
+                        @foreach($grid->rows() as $row)
+                            <tr {!! $row->rowAttributes() !!}>
+                                @foreach($grid->leftVisibleColumns() as $column)
+                                    <td {!! $row->columnAttributes($column->getName()) !!}>
+                                        {!! $row->column($column->getName()) !!}
+                                    </td>
+                                @endforeach
+                            </tr>
+                        @endforeach
+                        </tbody>
+                    </table>
+                </div>
+            @endif
+
+            @if ($grid->rightVisibleColumns()->isNotEmpty() || $grid->rightVisibleComplexColumns()->isNotEmpty())
+                <div class="table-wrap table-fixed table-fixed-right" data-height="{{ $tableHeight }}">
+                    <table class="custom-data-table  {{ $grid->formatTableClass() }} ">
+                        <thead>
+                        @if ($grid->getVisibleComplexHeaders())
+                            <tr>
+                                @foreach($grid->rightVisibleComplexColumns() as $header)
+                                    {!! $header->render() !!}
+                                @endforeach
+                            </tr>
+                            <tr>
+                                @foreach($grid->rightVisibleComplexColumns() as $header)
+                                    @if ($header->getColumnNames()->count() > 1)
+                                        @foreach($header->columns() as $column)
+                                            <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                        @endforeach
+                                    @endif
+                                @endforeach
+                            </tr>
+                        @else
+                            <tr>
+                                @foreach($grid->rightVisibleColumns() as $column)
+                                    <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                @endforeach
+                            </tr>
+                        @endif
+
+                        </thead>
+
+                        <tbody>
+
+                        @foreach($grid->rows() as $row)
+                            <tr {!! $row->rowAttributes() !!}>
+                                @foreach($grid->rightVisibleColumns() as $column)
+                                    <td {!! $row->columnAttributes($column->getName()) !!}>
+                                        {!! $row->column($column->getName()) !!}
+                                    </td>
+                                @endforeach
+                            </tr>
+                        @endforeach
+                        </tbody>
+                    </table>
+                </div>
+            @endif
+        </div>
+    </div>
+
+    {!! $grid->renderFooter() !!}
+
+    {!! $grid->renderPagination() !!}
+@else
+<div class="dcat-box custom-data-table async-{{ $tableId }}">
+    @include('admin::grid.table-toolbar')
+
+    {!! $grid->renderFilter() !!}
+
+    <div class="async-body">
+        {!! $grid->renderHeader() !!}
+
+        <div class="table-responsive table-wrapper {{ $grid->option('table_collapse') ? 'table-collapse' : '' }}">
+            <div class="tables-container">
+                <div class="table-wrap table-main" data-height="{{ $tableHeight }}">
+                    <table class="custom-data-table async-table {{ $grid->formatTableClass() }}" id="{{ $tableId }}">
+                        <thead>
+                        @if ($headers = $grid->getVisibleComplexHeaders())
+                            <tr>
+                                @foreach($headers as $header)
+                                    {!! $header->render() !!}
+                                @endforeach
+                            </tr>
+                        @endif
+                        <tr>
+                            @foreach($grid->getVisibleColumns() as $column)
+                                <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                            @endforeach
+                        </tr>
+                        </thead>
+
+                        @if ($grid->hasQuickCreate())
+                            {!! $grid->renderQuickCreate() !!}
+                        @endif
+
+                        <tbody>
+                            <tr>
+                                <td colspan="{!! count($grid->getVisibleColumnNames()) !!}">
+                                    <div style="margin:5px 0 0 10px;"><span class="help-block" style="margin-bottom:0"><i class="feather icon-alert-circle"></i>&nbsp;{{ trans('admin.no_data') }}</span></div>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+        {!! $grid->renderFooter() !!}
+    </div>
+</div>
+@endif

+ 87 - 0
resources/views/distributor/grid/async-table.blade.php

@@ -0,0 +1,87 @@
+@if($grid->isAsyncRequest())
+    {!! $grid->renderHeader() !!}
+
+    <div class="{!! $grid->formatTableParentClass() !!}">
+        <table class="async-table {{ $grid->formatTableClass() }}" id="{{ $tableId }}" >
+            <thead>
+            @if ($headers = $grid->getVisibleComplexHeaders())
+                <tr>
+                    @foreach($headers as $header)
+                        {!! $header->render() !!}
+                    @endforeach
+                </tr>
+            @endif
+            <tr>
+                @foreach($grid->getVisibleColumns() as $column)
+                    <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                @endforeach
+            </tr>
+            </thead>
+
+            @if ($grid->hasQuickCreate())
+                {!! $grid->renderQuickCreate() !!}
+            @endif
+
+            <tbody>
+            @foreach($grid->rows() as $row)
+                <tr {!! $row->rowAttributes() !!}>
+                    @foreach($grid->getVisibleColumnNames() as $name)
+                        <td {!! $row->columnAttributes($name) !!}>{!! $row->column($name) !!}</td>
+                    @endforeach
+                </tr>
+            @endforeach
+            @if ($grid->rows()->isEmpty())
+                <tr>
+                    <td colspan="{!! count($grid->getVisibleColumnNames()) !!}">
+                        <div style="margin:5px 0 0 10px;"><span class="help-block" style="margin-bottom:0"><i class="feather icon-alert-circle"></i>&nbsp;{{ trans('admin.no_data') }}</span></div>
+                    </td>
+                </tr>
+            @endif
+            </tbody>
+        </table>
+    </div>
+
+    {!! $grid->renderFooter() !!}
+
+    {!! $grid->renderPagination() !!}
+@else
+    <div class="dcat-box async-{{ $tableId }}">
+
+        <div class="d-block pb-0">
+            @include('admin::grid.table-toolbar')
+        </div>
+
+        {!! $grid->renderFilter() !!}
+
+        <div class="async-body">
+            {!! $grid->renderHeader() !!}
+
+            <div class="{!! $grid->formatTableParentClass() !!}">
+                <table class="async-table {{ $grid->formatTableClass() }}" id="{{ $tableId }}" >
+                    <thead>
+                    @if ($headers = $grid->getVisibleComplexHeaders())
+                        <tr>
+                            @foreach($headers as $header)
+                                {!! $header->render() !!}
+                            @endforeach
+                        </tr>
+                    @endif
+                    <tr>
+                        @foreach($grid->getVisibleColumns() as $column)
+                            <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                        @endforeach
+                    </tr>
+                    </thead>
+
+                    <tbody>
+                    <tr>
+                        <td colspan="{!! count($grid->getVisibleColumnNames()) !!}">&nbsp;</td>
+                    </tr>
+                    </tbody>
+                </table>
+            </div>
+
+            {!! $grid->renderFooter() !!}
+        </div>
+    </div>
+@endif

+ 37 - 0
resources/views/distributor/grid/batch-actions.blade.php

@@ -0,0 +1,37 @@
+@if(! $isHoldSelectAllCheckbox)
+<div class="btn-group dropdown  {{$selectAllName}}-btn" style="display:none;margin-right: 3px;z-index: 100">
+    <button type="button" class="btn btn-white dropdown-toggle btn-mini" data-toggle="dropdown">
+        <span class="d-none d-sm-inline selected"></span>
+        <span class="caret"></span>
+        <span class="sr-only"></span>
+    </button>
+    <ul class="dropdown-menu" role="menu">
+        @foreach($actions as $action)
+            @if ($action instanceof Dcat\Admin\Grid\Tools\ActionDivider)
+                <li class="dropdown-divider"></li>
+            @else
+                <li class="dropdown-item">
+                    {!! $action->render() !!}
+                </li>
+            @endif
+        @endforeach
+    </ul>
+</div>
+@endif
+
+<script>
+Dcat.init('.{{ $parent->getRowName() }}-checkbox', function ($this) {
+    $this.on('change', function () {
+        var btn = $('.{{ $selectAllName }}-btn'), selected = Dcat.grid.selectedRows('{{ $parent->getName() }}').length;
+
+        if (selected) {
+            btn.show()
+        } else {
+            btn.hide()
+        }
+        setTimeout(function () {
+            btn.find('.selected').html("{!! trans('admin.grid_items_selected') !!}".replace('{n}', selected));
+        }, 50)
+    })
+})
+</script>

+ 54 - 0
resources/views/distributor/grid/column-selector.blade.php

@@ -0,0 +1,54 @@
+<span class="dropdown column-selector" >
+    <button class="btn btn-primary btn-outline dropdown-toggle" data-toggle="dropdown">
+        <i class="fa fa-table"></i>
+        <span class="caret"></span>
+    </button>
+    <ul class="dropdown-menu" role="menu" style="min-width: 155px">
+        <li class="dropdown-item">
+            <ul class="selectors">
+                {!! $selectAll !!}
+            </ul>
+        </li>
+        <li class="dropdown-divider"></li>
+        <li class="dropdown-item">
+            <ul class="selectors">
+                {!! $checkbox !!}
+            </ul>
+        </li>
+    </ul>
+</span>
+
+<script once>
+    $('.column-selector input[name="_all_"]').on('change', function () {
+        $(this).parents('.column-selector').find('.column-select-item').prop('checked', this.checked).change()
+    });
+
+    var submit = Dcat.helpers.debounce(function ($this) {
+        var defaults = {!! json_encode($defaults) !!};
+        var selected = [];
+        var $parent = $this.parents('.column-selector');
+        var column = '{{ $columnName }}'
+
+        $parent.find('.column-select-item:checked').each(function () {
+            selected.push($(this).val());
+        });
+
+        if (selected.length == 0) {
+            return;
+        }
+
+        var url = new URL(location);
+
+        if (selected.sort().toString() == defaults.sort().toString()) {
+            url.searchParams.set(column, '');
+        } else {
+            url.searchParams.set(column, selected.join());
+        }
+
+        Dcat.reload(url.toString());
+    }, 200);
+
+    $('.column-selector .column-select-item').on('change', function () {
+        submit($(this));
+    });
+</script>

+ 111 - 0
resources/views/distributor/grid/displayer/dialogtree.blade.php

@@ -0,0 +1,111 @@
+<a href="javascript:void(0)" class="grid-dialog-tree"
+   data-url="{{ $url }}"
+   data-title="{{ $title }}"
+   data-checked="{{ $checkAll }}"
+   data-val="{{ $value }}">
+    <i class='feather icon-align-right'></i> {{ trans('admin.view') }}
+</a>
+
+<template>
+    <template id="dialog-tree-tpl">
+        <div class="jstree-wrapper p-1" style="border:0"><div class="da-tree" style="margin-top:10px"></div></div>
+    </template>
+</template>
+
+<script require="@jstree" once>
+    window.resolveDialogTree = function (options) {
+        var tpl = $('#dialog-tree-tpl').html(),
+            t = $(this),
+            val = t.data('val'),
+            url = t.data('url'),
+            title = t.data('title'),
+            ckall = t.data('checked'),
+            idx,
+            loading;
+
+        val = val ? String(val).split(',') : [];
+
+        if (url) {
+            if (loading) return;
+            loading = 1;
+
+            t.buttonLoading();
+            $.ajax(url, {data: {value: val}}).then(function (resp) {
+                loading = 0;
+                t.buttonLoading(false);
+
+                if (!resp.status) {
+                    return Dcat.error(resp.message || '系统繁忙,请稍后再试');
+                }
+
+                open(resp.value);
+            });
+        } else {
+            open(val);
+        }
+
+        function open(val) {
+            options.config.core.data = formatNodes(val, options.nodes);
+
+            idx = layer.open({
+                type: 1,
+                area: options.area,
+                content: tpl,
+                title: title,
+                success: function (a, idx) {
+                    var tree = $('#layui-layer'+idx).find('.da-tree');
+
+                    tree.on("loaded.jstree", function () {
+                        tree.jstree('open_all');
+                    }).jstree(options.config);
+                }
+            });
+
+            $(document).one('pjax:complete', function () {
+                layer.close(idx);
+            });
+        }
+
+        function formatNodes(value, all) {
+            var idColumn = options.columns.id,
+                textColumn = options.columns.text,
+                parentColumn = options.columns.parent,
+                nodes = [], i, v, parentId;
+
+            for (i in all) {
+                v = all[i];
+                if (!v[idColumn]) continue;
+
+                parentId = v[parentColumn] || '#';
+                if (!parentId || parentId == options.rootParentId || parentId == '0') {
+                    parentId = '#';
+                }
+
+                v['state'] = {'disabled': true};
+
+                if (ckall || (value && Dcat.helpers.inObject(value, v[idColumn]))) {
+                    v['state']['selected'] = true;
+                }
+
+                nodes.push({
+                    'id'     : v[idColumn],
+                    'text'   : v[textColumn] || null,
+                    'parent' : parentId,
+                    'state'  : v['state'],
+                });
+            }
+
+            return nodes;
+        }
+    }
+</script>
+
+<script require="@jstree">
+    var nodes = {!! json_encode($nodes) !!};
+    var options = {!! admin_javascript_json($options) !!};
+    var area = {!! json_encode($area) !!};
+
+    $('.grid-dialog-tree').off('click').on('click', function () {
+        resolveDialogTree.call(this, {config: options, nodes: nodes, area: area, rootParentId: '{!! $rootParentId !!}', columns: {!! json_encode($columnNames) !!}});
+    });
+</script>

+ 15 - 0
resources/views/distributor/grid/displayer/editinline/checkbox.blade.php

@@ -0,0 +1,15 @@
+@extends('admin::grid.displayer.editinline.template')
+
+@section('field')
+    {!! $checkbox !!}
+@endsection
+
+<script>
+@section('popover-content')
+    $template.find('input[type=checkbox]').each(function (index, checkbox) {
+        if($.inArray($(checkbox).attr('value'), $trigger.data('value')) >= 0) {
+            $(checkbox).attr('checked', true);
+        }
+    });
+@endsection
+</script>

+ 17 - 0
resources/views/distributor/grid/displayer/editinline/input.blade.php

@@ -0,0 +1,17 @@
+@extends('admin::grid.displayer.editinline.template')
+
+@section('field')
+    <input class="form-control ie-input"/>
+@endsection
+
+<script>
+@section('popover-content')
+    $template.find('input').attr('value', $trigger.data('value'));
+@endsection
+
+@section('popover-shown')
+    @if(! empty($mask))
+    $popover.find('.ie-input').inputmask({!! admin_javascript_json($mask) !!});
+    @endif
+@endsection
+</script>

+ 15 - 0
resources/views/distributor/grid/displayer/editinline/radio.blade.php

@@ -0,0 +1,15 @@
+@extends('admin::grid.displayer.editinline.template')
+
+@section('field')
+    {!! $radio !!}
+@endsection
+
+<script>
+@section('popover-content')
+    $template.find('input[type=radio]').each(function (index, checkbox) {
+        if(String($(checkbox).attr('value')) === String($trigger.data('value'))) {
+            $(checkbox).attr('checked', true);
+        }
+    });
+@endsection
+</script>

+ 178 - 0
resources/views/distributor/grid/displayer/editinline/template.blade.php

@@ -0,0 +1,178 @@
+<span class="ie-wrap">
+    <a
+        href="javascript:void(0);"
+        class="{{ $class }}"
+        data-editinline="popover"
+        data-temp="grid-editinline-{{ $type }}-{{ $name }}"
+        data-value="{{ $value }}"
+        data-original="{{ $value }}"
+        data-key="{{ $key }}"
+        data-name="{{ $name }}"
+        data-url="{!! $url !!}"
+        data-refresh="{{ $refresh }}"
+    >
+        <span class="ie-display">
+            {{ $display }}
+            @if(! $display)
+                <i class="feather icon-edit-2"></i>
+            @endif
+        </span>
+    </a>
+</span>
+
+<template>
+    <template id="grid-editinline-{{ $type }}-{{ $name }}">
+        <div class="ie-content ie-content-{{ $name }}" data-type="{{ $type }}">
+            <div class="ie-container">
+                @yield('field')
+                <div class="error"></div>
+            </div>
+            <div class="ie-action">
+                <button class="btn btn-primary btn-sm ie-submit">{{ __('admin.submit') }}</button>
+                <button class="btn btn-white btn-sm ie-cancel">{{ __('admin.cancel') }}</button>
+            </div>
+        </div>
+    </template>
+</template>
+
+<style>
+    .ie-action button {
+        margin: 10px 0 10px 10px;
+        float: right;
+    }
+    [data-editinline="popover"] {
+        border-bottom:dashed 1px @primary;
+        color: @primary;
+        display: inline-block;
+    }
+    body.dark-mode [data-editinline="popover"] {
+        color: @primary;
+        border-color: @primary;
+    }
+</style>
+
+<script>
+    function hide() {
+        $('[data-editinline="popover"]').popover('hide');
+    }
+
+    $('.{{ $class }}').popover({
+        html: true,
+        container: 'body',
+        trigger: 'manual',
+        sanitize: false,
+        placement: function (context, source) {
+            var position = $(source).position();
+            if (position.left < 100) return "right";
+            if (position.top < 110) return "bottom";
+            if ($(window).height() - $(source).offset().top < 370) {
+                return 'top';
+            }
+            return "bottom";
+        },
+        content: function () {
+            var $trigger = $(this);
+            var $template = $($('template#'+$(this).data('temp')).html());
+
+            @yield('popover-content')
+
+            return $template.prop("outerHTML");
+        }
+    }).on('shown.bs.popover', function (e) {
+
+        var $popover = $($(this).data('bs.popover').tip).find('.ie-content');
+        var $display = $(this).parents('.ie-wrap').find('.ie-display');
+        var $trigger = $(this);
+
+        $popover.data('display', $display);
+        $popover.data('trigger', $trigger);
+
+        @yield('popover-shown')
+
+    }).click(function () {
+        hide();
+        $(this).popover('toggle');
+    });
+</script>
+
+<script>
+    function hide() {
+        $('[data-editinline="popover"]').popover('hide');
+    }
+
+    $(document).off('click', '.ie-content .ie-cancel').on('click', '.ie-content .ie-cancel', hide)
+
+    $(document).off('click', '.ie-content .ie-submit').on('click', '.ie-content .ie-submit', function () {
+        var $popover = $(this).closest('.ie-content'),
+            $trigger = $popover.data('trigger'),
+            name = $trigger.data('name'),
+            original = $trigger.data('original'),
+            refresh = $trigger.data('refresh'),
+            val,
+            label;
+
+        switch($popover.data('type')) {
+            case 'input':
+            case 'textarea':
+                val = $popover.find('.ie-input').val();
+                label = val;
+                break;
+            case 'checkbox':
+                val = [];
+                label = [];
+                $popover.find('.ie-input:checked').each(function(){
+                    val.push($(this).val());
+                    label.push($(this).parent().text());
+                });
+                label = label.join(';');
+                break;
+            case 'radio':
+                val = $popover.find('.ie-input:checked').val();
+                label = $popover.find('.ie-input:checked').parent().text();
+                break;
+        }
+
+        if (val == original) {
+            hide();
+            return;
+        }
+
+        Dcat.NP.start();
+
+        var data = {};
+
+        if (name.indexOf('.') === -1) {
+            data[name] = val;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = val;
+        }
+        data['_inline_edit_'] = 1;
+
+        $.put({
+            url: $trigger.data('url'),
+            data: data,
+            error:function(a,b,c) {
+                Dcat.handleAjaxError(a, b, c);
+            },
+        }).done(function (res) {
+            Dcat.NP.done();
+            var data = res.data;
+            if (res.status === true) {
+                Dcat.success(data.message);
+                var $display = $popover.data('display');
+                $display.text(label);
+                if (! label) {
+                    $display.html('<i class="feather icon-edit-2"></i>');
+                }
+                $trigger.data('value', val).data('original', val);
+                hide();
+                refresh && Dcat.reload();
+            } else {
+                Dcat.error(data.message);
+            }
+        });
+    });
+</script>

+ 11 - 0
resources/views/distributor/grid/displayer/editinline/textarea.blade.php

@@ -0,0 +1,11 @@
+@extends('admin::grid.displayer.editinline.template')
+
+@section('field')
+    <textarea class="form-control ie-input" rows="{{ $rows }}"></textarea>
+@endsection
+
+<script>
+@section('popover-content')
+    $template.find('textarea').text($trigger.data('value'));
+@endsection
+</script>

+ 47 - 0
resources/views/distributor/grid/displayer/expand.blade.php

@@ -0,0 +1,47 @@
+<div>
+    <span class="grid-expand" data-url="{{ $url }}" data-inserted="0" data-id="{{ $key }}" data-key="{{ $dataKey }}" data-toggle="collapse" data-target="#grid-collapse-{{ $dataKey }}">
+       <a href="javascript:void(0)"><i class="feather icon-chevrons-right"></i>  {!! $button !!}</a>
+    </span>
+    <template class="grid-expand-{{ $dataKey }}">
+        <div id="grid-collapse-{{ $dataKey }}">{!! $html !!}</div>
+    </template>
+</div>
+
+<script once>
+    $('.grid-expand').off('click').on('click', function () {
+        var _th = $(this), url = _th.data('url');
+
+        if ($(this).data('inserted') == '0') {
+
+            var key = _th.data('key');
+            var row = _th.closest('tr');
+            var html = $('template.grid-expand-'+key).html();
+            var id = 'expand-'+key+Dcat.helpers.random(10);
+            var rowKey = _th.data('id');
+
+            $(this).attr('data-expand', '#'+id);
+            row.after("<tr id="+id+"><td colspan='"+(row.find('td').length)+"' style='padding:0 !important; border:0;height:0;'>"+html+"</td></tr>");
+
+            if (url) {
+                var collapse = $('#grid-collapse-'+key);
+                collapse.find('div').loading();
+                $('.dcat-loading').css({position: 'inherit', 'padding-top': '70px'});
+
+                Dcat.helpers.asyncRender(url+'&key='+rowKey, function (html) {
+                    collapse.html(html);
+                })
+            }
+            $(this).data('inserted', 1);
+        } else {
+            if ($("i", this).hasClass('icon-chevrons-right')) {
+                $(_th.data('expand')).show();
+            } else {
+                setTimeout(function() {
+                    $(_th.data('expand')).hide();
+                }, 250);
+            }
+        }
+
+        $("i", this).toggleClass("icon-chevrons-right icon-chevrons-down");
+    });
+</script>

+ 20 - 0
resources/views/distributor/grid/displayer/extensions/description.blade.php

@@ -0,0 +1,20 @@
+<div style="margin-bottom: 10px">{{ $value }}</div>
+
+@if($row->version && empty($row->new_version))
+    {{ trans('admin.version').' '.$row->version }}
+
+    @if($settingAction)
+        &nbsp;|&nbsp;
+        {!! $settingAction !!}
+    @endif
+@else
+    {!! $updateAction !!}
+
+    @if($settingAction && $row->new_version)
+        &nbsp;|&nbsp;
+        {!! $settingAction !!}
+    @endif
+@endif
+&nbsp;|&nbsp;
+
+<a href="javascript:void(0)">{{ trans('admin.view') }}</a>

+ 60 - 0
resources/views/distributor/grid/displayer/extensions/name.blade.php

@@ -0,0 +1,60 @@
+<div class="d-flex">
+    @if($row->logo)
+        <img data-action='preview-img' src='{!! $row->logo !!}' style='max-width:40px;max-height:40px;cursor:pointer' class='img img-thumbnail' />&nbsp;&nbsp;
+    @endif
+
+    <span class="ext-name">
+        @if($row->homepage)
+            <a href='{!! $row->homepage !!}' target='_blank' class="feather {{ $linkIcon }}"></a>
+        @endif
+
+        @if($row->alias)
+            {{ $row->alias }} <br><small class="text-80">{{ $value }}</small>
+        @else
+            {{ $value }}
+        @endif
+    </span>
+
+    @if($row->new_version || ! $row->version)
+        &nbsp;
+        <span class="badge bg-primary">New</span>
+    @endif
+</div>
+
+<div style="height: 10px"></div>
+
+@if($row->type === Dcat\Admin\Extend\ServiceProvider::TYPE_THEME)
+    <span>{{ trans('admin.theme') }}</span>
+@endif
+
+@if($row->version)
+    @if($row->type === Dcat\Admin\Extend\ServiceProvider::TYPE_THEME)
+        &nbsp;|&nbsp;
+    @endif
+
+    @if($row->enabled)
+        {!! $disableAction !!}
+    @else
+        {!! $enableAction !!}
+    @endif
+
+    <span class="hover-display" onclick="$(this).css({display: 'inline'})">
+        | {!! $uninstallAction !!}
+    </span>
+
+@endif
+
+<style>
+    .badge {
+        max-height: 22px
+    }
+    .hover-display {
+        display:none;
+    }
+    table tbody tr:hover .hover-display {
+        display: inline;
+    }
+    .ext-name {
+        font-size: 1.15rem;
+    }
+</style>

+ 44 - 0
resources/views/distributor/grid/displayer/select.blade.php

@@ -0,0 +1,44 @@
+<div class="input-group input-group-sm">
+    <select style="width: 100%;" class="grid-column-select" data-reload="{{ $refresh }}" data-url="{{ $url }}" data-name="{{ $column }}">
+        @foreach($options as $k => $v)
+            @php($selected = Dcat\Admin\Support\Helper::equal($k, $value)  ? 'selected' : '')
+
+            <option value="{{ $k }}" {{ $selected }}>{{ $v }}</option>
+        @endforeach
+
+    </select>
+</div>
+
+<script require="@select2?lang={{ config('app.locale') === 'en' ? '' : str_replace('_', '-', config('app.locale')) }}">
+    $('.grid-column-select').off('change').select2().on('change', function(){
+        var value = $(this).val(),
+            name = $(this).data('name'),
+            url = $(this).data('url'),
+            data = {},
+            reload = $(this).data('reload');
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+
+        Dcat.NP.start();
+        $.put({
+            url: url,
+            data: data,
+            success: function (d) {
+                Dcat.NP.done();
+                if (d.status) {
+                    Dcat.success(d.data.message);
+                    reload && Dcat.reload();
+                } else {
+                    Dcat.error(d.data.message);
+                }
+            }
+        });
+    });
+</script>

+ 51 - 0
resources/views/distributor/grid/displayer/switch.blade.php

@@ -0,0 +1,51 @@
+<input class="grid-column-switch" data-url="{{ $url }}" data-reload="{{ $refresh }}" data-size="small" name="{{ $column }}" {{ $checked }} type="checkbox" data-color="{{ $color }}"/>
+
+<script require="@switchery">
+    var swt = $('.grid-column-switch'),
+        that;
+    function initSwitchery() {
+        swt.parent().find('.switchery').remove();
+        swt.each(function () {
+            that = $(this);
+            new Switchery(that[0], that.data())
+        })
+    }
+    initSwitchery();
+
+    swt.off('change').on('change', function(e) {
+        var that = $(this),
+            url = that.data('url'),
+            reload = that.data('reload'),
+            checked = that.is(':checked'),
+            name = that.attr('name'),
+            data = {},
+            value = checked ? 1 : 0;
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+
+        Dcat.NP.start();
+
+        $.put({
+            url: url,
+            data: data,
+            success: function (d) {
+                Dcat.NP.done();
+                var msg = d.data.message || d.message;
+
+                if (d.status) {
+                    Dcat.success(msg);
+                    reload && Dcat.reload();
+                } else {
+                    Dcat.error(msg);
+                }
+            }
+        });
+    });
+</script>

+ 69 - 0
resources/views/distributor/grid/displayer/switchgroup.blade.php

@@ -0,0 +1,69 @@
+
+<style>
+    table.grid-switch-group tr td {
+        padding: 3px 0!important;
+        height:25px!important;
+        border: 0!important;
+    }
+</style>
+
+<table class="grid-switch-group">
+    @foreach($columns as $column => $label)
+        @php($checked = Illuminate\Support\Arr::get($row, $column) ? 'checked' : '')
+
+        <tr style="box-shadow: none;background: transparent">
+            <td>{{ $label }}:&nbsp;&nbsp;&nbsp;</td>
+            <td><input name="{{ $column }}" data-path="{{ $resource }}" data-key="{{ $key }}" {{ $checked }}
+                                                           type="checkbox" class="grid-column-switch-group" data-size="small" data-color="{{ $color }}"/></td>
+        </tr>
+    @endforeach
+</table>
+
+<script require="@switchery">
+    var swt = $('.grid-column-switch-group'),
+        reload = '{{ $refresh }}',
+        that;
+    function initSwitchery() {
+        swt.each(function() {
+            that = $(this);
+            that.parent().find('.switchery').remove();
+
+            new Switchery(that[0], that.data())
+        })
+    }
+    initSwitchery();
+    swt.off('change').change(function(e) {
+        var that = $(this),
+            id = that.data('key'),
+            url = that.data('path') + '/' + id,
+            checked = that.is(':checked'),
+            name = that.attr('name'),
+            data = {},
+            value = checked ? 1 : 0;
+
+        if (name.indexOf('.') === -1) {
+            data[name] = value;
+        } else {
+            name = name.split('.');
+
+            data[name[0]] = {};
+            data[name[0]][name[1]] = value;
+        }
+        Dcat.NP.start();
+
+        $.put({
+            url: url,
+            data: data,
+            success: function (d) {
+                Dcat.NP.done();
+                var msg = d.data.message || d.message;
+                if (d.status) {
+                    Dcat.success(msg);
+                    reload && Dcat.reload()
+                } else {
+                    Dcat.error(msg);
+                }
+            }
+        });
+    });
+</script>

+ 18 - 0
resources/views/distributor/grid/displayer/table.blade.php

@@ -0,0 +1,18 @@
+<table class="table table-hover" style="margin-bottom: 0;">
+    <thead>
+    <tr>
+        @foreach($titles as $column => $title)
+        <th>{{ $title }}</th>
+        @endforeach
+    </tr>
+    </thead>
+    <tbody>
+    @foreach($data as $datum)
+    <tr>
+        @foreach($datum as $key => $value)
+            <td>{{ $value }}</td>
+        @endforeach
+    </tr>
+    @endforeach
+    </tbody>
+</table>

+ 24 - 0
resources/views/distributor/grid/dropdown-actions.blade.php

@@ -0,0 +1,24 @@
+@if (!empty($default) || !empty($custom))
+<div class="grid-dropdown-actions dropdown">
+    <a href="#" style="padding:0 10px;" data-toggle="dropdown">
+        <i class="feather icon-more-vertical"></i>
+    </a>
+    <ul class="dropdown-menu" style="left: -65px;">
+
+        @foreach($default as $action)
+            <li class="dropdown-item">{!! Dcat\Admin\Support\Helper::render($action) !!}</li>
+        @endforeach
+
+        @if(!empty($custom))
+
+            @if(!empty($default))
+                <li class="dropdown-divider"></li>
+            @endif
+
+            @foreach($custom as $action)
+                <li class="dropdown-item">{!! $action !!}</li>
+            @endforeach
+        @endif
+    </ul>
+</div>
+@endif

+ 146 - 0
resources/views/distributor/grid/fixed-table.blade.php

@@ -0,0 +1,146 @@
+<div class="dcat-box custom-data-table">
+    @include('admin::grid.table-toolbar')
+
+    {!! $grid->renderFilter() !!}
+
+    {!! $grid->renderHeader() !!}
+
+    <div class="table-responsive table-wrapper {{ $grid->option('table_collapse') ? 'table-collapse' : '' }}">
+        <div class="tables-container">
+            <div class="table-wrap table-main" data-height="{{ $tableHeight }}">
+                <table class="custom-data-table {{ $grid->formatTableClass() }}" id="{{ $tableId }}">
+                    <thead>
+                    @if ($headers = $grid->getVisibleComplexHeaders())
+                        <tr>
+                            @foreach($headers as $header)
+                                {!! $header->render() !!}
+                            @endforeach
+                        </tr>
+                    @endif
+                    <tr>
+                        @foreach($grid->getVisibleColumns() as $column)
+                            <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                        @endforeach
+                    </tr>
+                    </thead>
+
+                    @if ($grid->hasQuickCreate())
+                        {!! $grid->renderQuickCreate() !!}
+                    @endif
+
+                    <tbody>
+                    @foreach($grid->rows() as $row)
+                        <tr {!! $row->rowAttributes() !!}>
+                            @foreach($grid->getVisibleColumnNames() as $name)
+                                <td {!! $row->columnAttributes($name) !!}>
+                                    {!! $row->column($name) !!}
+                                </td>
+                            @endforeach
+                        </tr>
+                    @endforeach
+                    @if ($grid->rows()->isEmpty())
+                        <tr>
+                            <td colspan="{!! count($grid->getVisibleColumnNames()) !!}">
+                                <div style="margin:5px 0 0 10px;"><span class="help-block" style="margin-bottom:0"><i class="feather icon-alert-circle"></i>&nbsp;{{ trans('admin.no_data') }}</span></div>
+                            </td>
+                        </tr>
+                    @endif
+                    </tbody>
+                </table>
+            </div>
+
+            @if ($grid->leftVisibleColumns()->isNotEmpty() || $grid->leftVisibleComplexColumns()->isNotEmpty())
+                <div class="table-wrap table-fixed table-fixed-left" data-height="{{ $tableHeight }}">
+                    <table class="custom-data-table {{ $grid->formatTableClass() }} ">
+                        <thead>
+
+                        @if ($grid->getVisibleComplexHeaders())
+                            <tr>
+                                @foreach($grid->leftVisibleComplexColumns() as $header)
+                                    {!! $header->render() !!}
+                                @endforeach
+                            </tr>
+                            <tr>
+                            @foreach($grid->leftVisibleComplexColumns() as $header)
+                                @if ($header->getColumnNames()->count() > 1)
+                                    @foreach($header->columns() as $column)
+                                        <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                    @endforeach
+                                @endif
+                            @endforeach
+                            </tr>
+                        @else
+                            <tr>
+                                @foreach($grid->leftVisibleColumns() as $column)
+                                    <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                @endforeach
+                            </tr>
+                        @endif
+                        </thead>
+                        <tbody>
+
+                        @foreach($grid->rows() as $row)
+                            <tr {!! $row->rowAttributes() !!}>
+                                @foreach($grid->leftVisibleColumns() as $column)
+                                    <td {!! $row->columnAttributes($column->getName()) !!}>
+                                        {!! $row->column($column->getName()) !!}
+                                    </td>
+                                @endforeach
+                            </tr>
+                        @endforeach
+                        </tbody>
+                    </table>
+                </div>
+            @endif
+
+            @if ($grid->rightVisibleColumns()->isNotEmpty() || $grid->rightVisibleComplexColumns()->isNotEmpty())
+                <div class="table-wrap table-fixed table-fixed-right" data-height="{{ $tableHeight }}">
+                    <table class="custom-data-table {{ $grid->formatTableClass() }} ">
+                        <thead>
+                        @if ($grid->getVisibleComplexHeaders())
+                            <tr>
+                                @foreach($grid->rightVisibleComplexColumns() as $header)
+                                    {!! $header->render() !!}
+                                @endforeach
+                            </tr>
+                            <tr>
+                            @foreach($grid->rightVisibleComplexColumns() as $header)
+                                @if ($header->getColumnNames()->count() > 1)
+                                    @foreach($header->columns() as $column)
+                                        <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                    @endforeach
+                                @endif
+                            @endforeach
+                            </tr>
+                        @else
+                            <tr>
+                                @foreach($grid->rightVisibleColumns() as $column)
+                                    <th {!! $column->formatTitleAttributes() !!}>{!! $column->getLabel() !!}{!! $column->renderHeader() !!}</th>
+                                @endforeach
+                            </tr>
+                        @endif
+
+                        </thead>
+
+                        <tbody>
+
+                        @foreach($grid->rows() as $row)
+                            <tr {!! $row->rowAttributes() !!}>
+                                @foreach($grid->rightVisibleColumns() as $column)
+                                    <td {!! $row->columnAttributes($column->getName()) !!}>
+                                        {!! $row->column($column->getName()) !!}
+                                    </td>
+                                @endforeach
+                            </tr>
+                        @endforeach
+                        </tbody>
+                    </table>
+                </div>
+            @endif
+        </div>
+    </div>
+
+    {!! $grid->renderFooter() !!}
+
+    {!! $grid->renderPagination() !!}
+</div>

+ 51 - 0
resources/views/distributor/grid/image.blade.php

@@ -0,0 +1,51 @@
+<div class="box">
+    @if(isset($title))
+        <div class="box-header with-border">
+            <h3 class="box-title"> {{ $title }}</h3>
+        </div>
+    @endif
+
+    <div class="box-header with-border">
+        <div class="pull-right">
+            {!! $grid->renderExportButton() !!}
+            {!! $grid->renderCreateButton() !!}
+        </div>
+        <span>
+            {!! $grid->renderHeaderTools() !!}
+        </span>
+    </div>
+
+    {!! $grid->renderFilter() !!}
+
+    <div class="box-body table-responsive no-padding">
+        <ul class="mailbox-attachments clearfix">
+            @foreach($grid->rows() as $row)
+                <li>
+                    <span class="mailbox-attachment-icon has-img">
+                        <img src="{!! isset($server) ? $server . '/' . $row->column($image_column) : \Illuminate\Support\Facades\Storage::disk(config('admin.upload.disk'))->url($row->column($image_column)) !!}" alt="Attachment">
+                    </span>
+                    <div class="mailbox-attachment-info">
+                        <a href="#" class="mailbox-attachment-name" style="word-break:break-all;">
+                            <i class="fa fa-camera"></i>&nbsp;&nbsp;
+                            {!! isset($text_column) ? $row->column($text_column) : '' !!}
+                        </a>
+                        <span class="mailbox-attachment-size">
+                          <input type="checkbox" class="grid-item" data-id="{{ $row->id() }}" />
+                            <span class="pull-right">
+                                {!! $row->column('__actions__') !!}
+                                <a href="{!! isset($server) ? $server . '/' . $row->column($image_column) : \Illuminate\Support\Facades\Storage::disk(config('admin.upload.disk'))->url($row->column($image_column)) !!}" target="_blank" download="custom-filename.jpg">
+                                    <i class="fa fa-cloud-download"></i>
+                                </a>
+                            </span>
+                        </span>
+                    </div>
+                </li>
+            @endforeach
+        </ul>
+    </div>
+
+    <div class="box-footer clearfix">
+        {!! $grid->paginator() !!}
+    </div>
+    <!-- /.box-body -->
+</div>

+ 35 - 0
resources/views/distributor/grid/pagination.blade.php

@@ -0,0 +1,35 @@
+<ul class="pagination pagination-sm no-margin pull-right shadow-100" style="border-radius: 1.5rem">
+    <!-- Previous Page Link -->
+    @if ($paginator->onFirstPage())
+    <li class="page-item previous disabled"><span class="page-link"></span></li>
+    @else
+    <li class="page-item previous"><a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev"></a></li>
+    @endif
+
+    @if(! empty($elements))
+    @foreach ($elements as $element)
+        <!-- "Three Dots" Separator -->
+        @if (is_string($element))
+        <li class="page-item disabled"><span class="page-link">{{ $element }}</span></li>
+        @endif
+
+        <!-- Array Of Links -->
+        @if (is_array($element))
+            @foreach ($element as $page => $url)
+                @if ($page == $paginator->currentPage())
+                <li class="page-item active"><span class="page-link">{{ $page }}</span></li>
+                @else
+                <li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
+                @endif
+            @endforeach
+        @endif
+    @endforeach
+    @endif
+
+    <!-- Next Page Link -->
+    @if ($paginator->hasMorePages())
+    <li class="page-item next"><a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next"></a></li>
+    @else
+    <li class="page-item next disabled"><span class="page-link"></span></li>
+    @endif
+</ul>

+ 3 - 0
resources/views/distributor/grid/quick-create/date.blade.php

@@ -0,0 +1,3 @@
+<div class="input-group input-group-sm quick-form-field">
+    <input style="width: 125px;" {!! $attributes !!} placeholder="{{ $label }}" />
+</div>

+ 88 - 0
resources/views/distributor/grid/quick-create/form.blade.php

@@ -0,0 +1,88 @@
+<thead>
+<tr class="{{ $elementClass }} quick-create" style="cursor: pointer">
+    <td colspan="{{ $columnCount }}" style="background: {{ Dcat\Admin\Admin::color()->darken('#ededed', 1) }}">
+        <span class="create cursor-pointer" style="display: block;">
+             <i class="feather icon-plus"></i>&nbsp;{{ __('admin.quick_create') }}
+        </span>
+
+        <form class="form-inline create-form" style="display: none;" method="post">
+            @foreach($fields as $field)
+                &nbsp;{!! $field->render() !!}
+            @endforeach
+                &nbsp;
+            &nbsp;
+            <button type="submit" class="btn btn-primary btn-sm">{{ __('admin.submit') }}</button>&nbsp;
+            &nbsp;
+            <a href="javascript:void(0);" class="cancel">{{ __('admin.cancel') }}</a>
+        </form>
+    </td>
+</tr>
+</thead>
+
+<script>
+    var ctr = $('.{!! $elementClass !!}'),
+        btn = $('.quick-create-button-{!! $uniqueName !!}');
+
+    btn.on('click', function () {
+        ctr.toggle().click();
+    });
+
+    ctr.on('click', function () {
+        ctr.find('.create-form').show();
+        ctr.find('.create').hide();
+    });
+
+    ctr.find('.cancel').on('click', function () {
+        if (btn.length) {
+            ctr.hide();
+            return;
+        }
+
+        ctr.find('.create-form').hide();
+        ctr.find('.create').show();
+        return false;
+    });
+
+    ctr.find('.create-form').submit(function (e) {
+        e.preventDefault();
+
+        if (ctr.attr('submitting')) {
+            return;
+        }
+
+        var btn = $(this).find(':submit').buttonLoading();
+
+        ctr.attr('submitting', 1);
+
+        $.ajax({
+            url: '{!! $url !!}',
+            type: '{!! $method !!}',
+            data: $(this).serialize(),
+            success: function(data) {
+                ctr.attr('submitting', '');
+                btn.buttonLoading(false);
+
+                Dcat.handleJsonResponse(data);
+            },
+            error:function(xhq){
+                btn.buttonLoading(false);
+                ctr.attr('submitting', '');
+                var json = xhq.responseJSON;
+                if (typeof json === 'object') {
+                    if (json.message) {
+                        Dcat.error(json.message);
+                    } else if (json.errors) {
+                        var i, errors = [];
+                        for (i in json.errors) {
+                            errors.push(json.errors[i].join("<br>"));
+                        }
+
+                        Dcat.error(errors.join("<br>"));
+                    }
+                }
+            }
+        });
+
+        return false;
+    });
+</script>

+ 10 - 0
resources/views/distributor/grid/quick-create/multipleselect.blade.php

@@ -0,0 +1,10 @@
+<div class="input-group input-group-sm quick-form-field">
+    <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}" {!! $attributes !!} multiple data-placeholder="{{ $label }}">
+
+        <option value=""></option>
+        @foreach($options as $select => $option)
+            <option value="{{$select}}" {{ $select == old($column, $value) ?'selected':'' }}>{{$option}}</option>
+        @endforeach
+    </select>
+</div>
+

+ 12 - 0
resources/views/distributor/grid/quick-create/select.blade.php

@@ -0,0 +1,12 @@
+<div class="input-group input-group-sm quick-form-field">
+    <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}" {!! $attributes !!} >
+
+        <option value=""></option>
+        @foreach($options as $select => $option)
+            <option value="{{$select}}" {{ Dcat\Admin\Support\Helper::equal($select, old($column, $value)) ?'selected':'' }}>{{$option}}</option>
+        @endforeach
+    </select>
+</div>
+
+@include('admin::form.select-script')
+

+ 15 - 0
resources/views/distributor/grid/quick-create/selectresource.blade.php

@@ -0,0 +1,15 @@
+<div class="input-group input-group-sm quick-form-field">
+    <app></app>
+    <div class="input-group-sm">
+        @if(!$disabled)
+            <input name="{{$name}}" type="hidden" />
+        @endif
+        <div {!! $attributes !!}>
+        </div>
+        <div class="input-group-append">
+            <div class="btn btn-sm btn-{{$style}} " id="{{ $btnId }}">
+                &nbsp;<i class="feather icon-arrow-up"></i>&nbsp;
+            </div>
+        </div>
+    </div>
+</div>

+ 8 - 0
resources/views/distributor/grid/quick-create/tags.blade.php

@@ -0,0 +1,8 @@
+<div class="input-group input-group-sm quick-form-field">
+    <select class="form-control {{$class}}" style="width: 100%;" name="{{$name}}[]" multiple="multiple" data-placeholder="{{ $label }}" {!! $attributes !!} >
+        @foreach($options as $key => $option)
+            <option value="{{ $keyAsValue ? $key : $option}}" {{ in_array($option, $value) ? 'selected' : '' }}>{{$option}}</option>
+        @endforeach
+    </select>
+    <input type="hidden" name="{{$name}}[]" />
+</div>

+ 3 - 0
resources/views/distributor/grid/quick-create/text.blade.php

@@ -0,0 +1,3 @@
+<div class="input-group input-group-sm quick-form-field">
+    <input {!! $attributes !!} placeholder="{{ $label }}"/>
+</div>

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov