Преглед изворни кода

add sortable user/order table

兔姬桑 пре 4 година
родитељ
комит
78de053306

+ 1 - 8
app/Http/Controllers/Admin/LogsController.php

@@ -55,14 +55,7 @@ class LogsController extends Controller
             });
         }
 
-        // 0-按创建时间降序、1-按创建时间升序 默认为按创建时间降序
-        if ($request->filled('sort') && $request->input('sort') === '1') {
-            $query->oldest();
-        } else {
-            $query->latest();
-        }
-
-        return view('admin.logs.order', ['orders' => $query->paginate(15)->appends($request->except('page'))]);
+        return view('admin.logs.order', ['orders' => $query->sortable(['id' => 'desc'])->paginate(15)->appends($request->except('page'))]);
     }
 
     // 流量日志

+ 1 - 1
app/Http/Controllers/Admin/UserController.php

@@ -76,7 +76,7 @@ class UserController extends Controller
         });
 
         return view('admin.user.index', [
-            'userList'   => $query->orderByDesc('id')->paginate(15)->appends($request->except('page')),
+            'userList'   => $query->sortable(['id' => 'desc'])->paginate(15)->appends($request->except('page')),
             'userGroups' => UserGroup::all()->pluck('name', 'id')->toArray(),
             'levels'     => Level::all()->pluck('name', 'level')->toArray(),
         ]);

+ 1 - 1
app/Http/Controllers/User/SubscribeController.php

@@ -50,7 +50,7 @@ class SubscribeController extends Controller
                 return $this->failed(trans('error.subscribe.baned_until', ['time' => $user->ban_time]));
             }
 
-            $unusedTraffic = $user->transfer_enable - $user->usedTraffic();
+            $unusedTraffic = $user->transfer_enable - $user->used_traffic;
             if ($unusedTraffic <= 0) {
                 return $this->failed(trans('error.subscribe.out'));
             }

+ 1 - 1
app/Http/Controllers/UserController.php

@@ -40,7 +40,7 @@ class UserController extends Controller
         }
         $user = auth()->user();
         $totalTransfer = $user->transfer_enable;
-        $usedTransfer = $user->usedTraffic();
+        $usedTransfer = $user->used_traffic;
         $unusedTraffic = $totalTransfer - $usedTransfer > 0 ? $totalTransfer - $usedTransfer : 0;
         $expireTime = $user->expired_at;
 

+ 4 - 0
app/Models/Order.php

@@ -6,12 +6,16 @@ use Auth;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasOne;
+use Kyslik\ColumnSortable\Sortable;
 
 /**
  * 订单.
  */
 class Order extends Model
 {
+    use Sortable;
+
+    public $sortable = ['id', 'sn', 'expired_at', 'created_at'];
     protected $table = 'order';
     protected $dates = ['expired_at'];
     protected $guarded = [];

+ 5 - 3
app/Models/User.php

@@ -9,6 +9,7 @@ use Illuminate\Database\Eloquent\Relations\HasManyThrough;
 use Illuminate\Database\Eloquent\Relations\HasOne;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 use Illuminate\Notifications\Notifiable;
+use Kyslik\ColumnSortable\Sortable;
 use Spatie\Permission\Traits\HasRoles;
 use Tymon\JWTAuth\Contracts\JWTSubject;
 
@@ -17,8 +18,9 @@ use Tymon\JWTAuth\Contracts\JWTSubject;
  */
 class User extends Authenticatable implements JWTSubject
 {
-    use Notifiable, HasRoles;
+    use Notifiable, HasRoles, Sortable;
 
+    public $sortable = ['id', 'credit', 'port', 't', 'expired_at'];
     protected $table = 'user';
     protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d'];
     protected $dates = ['expired_at', 'reset_time'];
@@ -26,10 +28,10 @@ class User extends Authenticatable implements JWTSubject
 
     public function usedTrafficPercentage()
     {
-        return round(($this->usedTraffic()) / $this->transfer_enable, 2);
+        return round(($this->used_traffic) / $this->transfer_enable, 2);
     }
 
-    public function usedTraffic(): int
+    public function getUsedTrafficAttribute(): int
     {
         return $this->d + $this->u;
     }

+ 1 - 0
composer.json

@@ -22,6 +22,7 @@
     "ip2location/ip2location-laravel": "^1.2",
     "ipip/db": "^1.0",
     "jenssegers/agent": "^2.6",
+    "kyslik/column-sortable": "^6.4",
     "laravel-notification-channels/bearychat": "^1.4",
     "laravel-notification-channels/telegram": "^0.5",
     "laravel/framework": "^7.30",

+ 73 - 7
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "d2b1ca543427ed7f9993d7350c36a649",
+    "content-hash": "671c903827f0d1af596a129c2cb560bc",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -2006,6 +2006,73 @@
             ],
             "time": "2020-06-13T08:05:20+00:00"
         },
+        {
+            "name": "kyslik/column-sortable",
+            "version": "6.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Kyslik/column-sortable.git",
+                "reference": "44f9da98acd31b2e871d0074bd638998990888b1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Kyslik/column-sortable/zipball/44f9da98acd31b2e871d0074bd638998990888b1",
+                "reference": "44f9da98acd31b2e871d0074bd638998990888b1",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "illuminate/database": "5.8.*|^6.0|^7.0|^8.0",
+                "illuminate/support": "5.8.*|^6.0|^7.0|^8.0",
+                "php": ">=7.2"
+            },
+            "require-dev": {
+                "orchestra/testbench": "^5.0",
+                "phpunit/phpunit": "^8.5"
+            },
+            "type": "package",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Kyslik\\ColumnSortable\\ColumnSortableServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Kyslik\\ColumnSortable\\": "src/ColumnSortable/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Martin Kiesel",
+                    "email": "[email protected]",
+                    "role": "Developer and maintainer"
+                }
+            ],
+            "description": "Package for handling column sorting in Laravel 6.x",
+            "keywords": [
+                "column",
+                "laravel",
+                "sort",
+                "sortable",
+                "sorting"
+            ],
+            "support": {
+                "issues": "https://github.com/Kyslik/column-sortable/issues",
+                "source": "https://github.com/Kyslik/column-sortable/tree/6.4.1"
+            },
+            "time": "2021-07-09T12:15:54+00:00"
+        },
         {
             "name": "laravel-lang/lang",
             "version": "8.1.3",
@@ -9664,16 +9731,16 @@
         },
         {
             "name": "facade/ignition",
-            "version": "2.10.2",
+            "version": "2.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/facade/ignition.git",
-                "reference": "43688227bbf27c43bc1ad83af224f135b6ef0ff4"
+                "reference": "dc6818335f50ccf0b90284784718ea9a82604286"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/facade/ignition/zipball/43688227bbf27c43bc1ad83af224f135b6ef0ff4",
-                "reference": "43688227bbf27c43bc1ad83af224f135b6ef0ff4",
+                "url": "https://api.github.com/repos/facade/ignition/zipball/dc6818335f50ccf0b90284784718ea9a82604286",
+                "reference": "dc6818335f50ccf0b90284784718ea9a82604286",
                 "shasum": "",
                 "mirrors": [
                     {
@@ -9687,7 +9754,6 @@
                 "ext-mbstring": "*",
                 "facade/flare-client-php": "^1.6",
                 "facade/ignition-contracts": "^1.0.2",
-                "filp/whoops": "^2.4",
                 "illuminate/support": "^7.0|^8.0",
                 "monolog/monolog": "^2.0",
                 "php": "^7.2.5|^8.0",
@@ -9743,7 +9809,7 @@
                 "issues": "https://github.com/facade/ignition/issues",
                 "source": "https://github.com/facade/ignition"
             },
-            "time": "2021-06-11T06:57:25+00:00"
+            "time": "2021-07-12T15:55:51+00:00"
         },
         {
             "name": "facade/ignition-contracts",

+ 121 - 0
config/columnsortable.php

@@ -0,0 +1,121 @@
+<?php
+
+return [
+
+    /*
+    spec columns
+    */
+    'columns'                       => [
+        'alpha'   => [
+            'rows'  => ['description', 'email', 'name', 'slug'],
+            'class' => 'fas fa-sort-alpha',
+        ],
+        'amount'  => [
+            'rows'  => ['amount', 'price', 'credit'],
+            'class' => 'fas fa-sort-amount',
+        ],
+        'numeric' => [
+            'rows'  => ['created_at', 'updated_at', 'expired_at', 't', 'level', 'id', 'phone_number', 'port'],
+            'class' => 'fas fa-sort-numeric',
+        ],
+    ],
+
+    /*
+    whether icons should be enabled
+     */
+    'enable_icons'                  => true,
+
+    /*
+    defines icon set to use when sorted data is none above (alpha nor amount nor numeric)
+     */
+    'default_icon_set'              => 'fas fa-sort',
+
+    /*
+    icon that shows when generating sortable link while column is not sorted
+     */
+    'sortable_icon'                 => 'fas fa-sort',
+
+    /*
+    generated icon is clickable non-clickable (default)
+     */
+    'clickable_icon'                => true,
+
+    /*
+    icon and text separator (any string)
+    in case of 'clickable_icon' => true; separator creates possibility to style icon and anchor-text properly
+     */
+    'icon_text_separator'           => ' ',
+
+    /*
+    suffix class that is appended when ascending direction is applied
+     */
+    'asc_suffix'                    => '-up',
+
+    /*
+    suffix class that is appended when descending direction is applied
+     */
+    'desc_suffix'                   => '-down',
+
+    /*
+    default anchor class, if value is null none is added
+     */
+    'anchor_class'                  => null,
+
+    /*
+    default active anchor class, if value is null none is added
+     */
+    'active_anchor_class'           => null,
+
+    /*
+    default sort direction anchor class, if value is null none is added
+     */
+    'direction_anchor_class_prefix' => null,
+
+    /*
+    relation - column separator ex: detail.phone_number means relation "detail" and column "phone_number"
+     */
+    'uri_relation_column_separator' => '.',
+
+    /*
+    formatting function applied to name of column, use null to turn formatting off
+     */
+    'formatting_function'           => 'ucfirst',
+
+    /*
+    apply formatting function to custom titles as well as column names
+     */
+    'format_custom_titles'          => true,
+
+    /*
+    inject title parameter in query strings, use null to turn injection off
+    example: 'inject_title' => 't' will result in ..user/?t="formatted title of sorted column"
+     */
+    'inject_title_as'               => null,
+
+    /*
+    allow request modification, when default sorting is set but is not in URI (first load)
+     */
+    'allow_request_modification'    => true,
+
+    /*
+    default direction for: $user->sortable('id') usage
+     */
+    'default_direction'             => 'asc',
+
+    /*
+    default direction for non-sorted columns
+     */
+    'default_direction_unsorted'    => 'asc',
+
+    /*
+    use the first defined sortable column (Model::$sortable) as default
+    also applies if sorting parameters are invalid for example: 'sort' => 'name', 'direction' => ''
+     */
+    'default_first_column'          => false,
+
+    /*
+    join type: join vs leftJoin (default leftJoin)
+    for more information see https://github.com/Kyslik/column-sortable/issues/59
+    */
+    'join_type'                     => 'leftJoin',
+];

+ 1 - 0
resources/views/admin/layouts.blade.php

@@ -1,6 +1,7 @@
 @extends('_layout')
 @section('title', sysConfig('website_name'))
 @section('layout_css')
+    <link href="/assets/global/fonts/font-awesome/css/all.min.css" rel="stylesheet">
     @yield('css')
 @endsection
 @section('body_class', 'dashboard')

+ 10 - 18
resources/views/admin/logs/order.blade.php

@@ -2,6 +2,12 @@
 @section('css')
     <link href="/assets/global/vendor/bootstrap-table/bootstrap-table.min.css" rel="stylesheet">
     <link href="/assets/global/vendor/bootstrap-datepicker/bootstrap-datepicker.min.css" rel="stylesheet">
+    <style>
+        .table a {
+            color: #76838f;
+            text-decoration: none;
+        }
+    </style>
 @endsection
 @section('content')
     <div class="page-content container-fluid">
@@ -60,18 +66,6 @@
                             <option value="2">已完成</option>
                         </select>
                     </div>
-                    <div class="form-group col-lg-3 col-sm-6">
-                        <div class="d-flex align-items-center">
-                            <div class="radio-custom radio-primary radio-inline">
-                                <input type="radio" name="sort" value="0" checked/>
-                                <label for="type">降序</label>
-                            </div>
-                            <div class="radio-custom radio-primary radio-inline">
-                                <input type="radio" name="sort" value="1"/>
-                                <label for="type">升序</label>
-                            </div>
-                        </div>
-                    </div>
                     <div class="form-group col-lg-2 col-sm-6 btn-group">
                         <button type="submit" class="btn btn-primary">搜 索</button>
                         <a href="{{route('admin.order')}}" class="btn btn-danger">{{trans('common.reset')}}</a>
@@ -80,17 +74,17 @@
                 <table class="text-md-center" data-toggle="table" data-mobile-responsive="true">
                     <thead class="thead-default">
                     <tr>
-                        <th> #</th>
+                        <th> @sortablelink('id', '#')</th>
                         <th> 用户账号</th>
-                        <th> 订单号</th>
+                        <th> @sortablelink('sn', '订单号')</th>
                         <th> 商品</th>
-                        <th> 过期时间</th>
+                        <th> @sortablelink('expired_at', '过期时间')</th>
                         <th> 优惠券</th>
                         <th> 原价</th>
                         <th> 实价</th>
                         <th> 支付方式</th>
                         <th> 订单状态</th>
-                        <th> 创建时间</th>
+                        <th> @sortablelink('created_at', '创建时间')</th>
                     </tr>
                     </thead>
                     <tbody>
@@ -161,8 +155,6 @@
             $('#is_coupon').val({{Request::query('is_coupon')}});
             $('#pay_way').val({{Request::query('pay_way')}});
             $('#status').val({{Request::query('status')}});
-            $("input[name='sort'][value='{{Request::query('sort')}}']").click();
-
             $('select').on('change', function() { this.form.submit(); });
         });
 

+ 6 - 6
resources/views/admin/user/index.blade.php

@@ -85,14 +85,14 @@
                 <table class="text-md-center" data-toggle="table" data-mobile-responsive="true">
                     <thead class="thead-default">
                     <tr>
-                        <th> #</th>
+                        <th> @sortablelink('id', '#')</th>
                         <th> 用户账号</th>
-                        <th> 余额</th>
-                        <th> 端口</th>
+                        <th> @sortablelink('credit', '余额')</th>
+                        <th> @sortablelink('port', '端口')</th>
                         <th> 订阅码</th>
                         <th> 流量使用</th>
-                        <th> 最后使用</th>
-                        <th> 有效期</th>
+                        <th> @sortablelink('t', '最后使用')</th>
+                        <th> @sortablelink('expired_at', '有效期')</th>
                         <th> {{trans('common.status')}}</th>
                         <th> 代理</th>
                         <th> {{trans('common.action')}}</th>
@@ -111,7 +111,7 @@
                                 <a href="javascript:" class="copySubscribeLink" data-clipboard-action="copy"
                                    data-clipboard-text="{{$user->subUrl()}}">{{$user->subscribe->code}}</a>
                             </td>
-                            <td> {{flowAutoShow($user->usedTraffic())}} / {{$user->transfer_enable_formatted}} </td>
+                            <td> {{flowAutoShow($user->used_traffic)}} / {{$user->transfer_enable_formatted}} </td>
                             <td> {{$user->t? date('Y-m-d H:i', $user->t): '未使用'}} </td>
 
                             <td>