瀏覽代碼

优化倒计时显示

兔姬桑 3 年之前
父節點
當前提交
e58cd84585
共有 4 個文件被更改,包括 179 次插入154 次删除
  1. 1 1
      readme.md
  2. 2 2
      resources/lang/en/user.php
  3. 2 2
      resources/lang/zh_CN/user.php
  4. 174 149
      resources/views/user/index.blade.php

+ 1 - 1
readme.md

@@ -10,7 +10,7 @@ Support but not limited to: Shadowsocks,ShadowsocksR,ShadowsocksRR,V2Ray,Trojan,
 - [Issues](https://github.com/ZBrettonYe/ProxyPanel/issues)
 - [UpdateLog](https://proxypanel.gitbook.io/wiki/updatelog)
 - [Upcoming](https://github.com/ZBrettonYe/ProxyPanel/projects/2)
-- [Telegram](https://t.me/joinchat/GUrO5hZsT3FOd79HAa9pcA)
+- [Telegram](https://t.me/+nW8AwsPPUsliYzg1)
 
 ## Funding
 Buy me a Coffee?

+ 2 - 2
resources/lang/en/user.php

@@ -10,12 +10,12 @@ return [
         'remain'           => 'Remain Data',
         'time'             => 'Period',
         'last_login'       => 'Last Login',
-        'reset'            => ':days days to next reset',
+        'reset'            => '{0}Data will be reset in <code id="restTime">:days</code>|{1} Data will be reset in :days day|restTime|[2,*] Data will be reset in :days days',
         'connect_password' => 'Proxy Connect Password',
         'reason'           => [
             'normal'            => 'Normal',
             'expired'           => 'Expired',
-            'overused'          => 'You have reach the <code>:data</code> GB hourly data spend limit<br/> Wait <code id="countdown">:min</code> to cool down',
+            'overused'          => 'You have reach the <code>:data</code> GB hourly data spend limit<br/> Wait <code id="banedTime">:min</code> to cool down',
             'traffic_exhausted' => 'OUT OF DATA',
             'unknown'           => 'UNKNOWN ERROR, Please try to refresh your browser first before contact admin for help',
         ],

+ 2 - 2
resources/lang/zh_CN/user.php

@@ -10,12 +10,12 @@ return [
         'remain'           => '剩余流量',
         'time'             => '套餐时长',
         'last_login'       => '最近登录',
-        'reset'            => '还有 :days 天重置',
+        'reset'            => '{0} 还有 <code id="restTime">:days</code> 重置流量|[1,*] 还有 :days 天重置流量',
         'connect_password' => '连接密码',
         'reason'           => [
             'normal'            => '账号一切正常',
             'expired'           => '您的账号套餐已过期',
-            'overused'          => '本时段使用流量超过 <code>:data</code> GB触发系统限制<br/> <code id="countdown">:min</code> 后解除限制',
+            'overused'          => '本时段使用流量超过 <code>:data</code> GB触发系统限制<br/> <code id="banedTime">:min</code> 后解除限制',
             'traffic_exhausted' => '您的账号[流量]消耗殆尽',
             'unknown'           => '未知原因,请尝试[刷新]你的浏览器!多次无果后再请开工单联系管理',
         ],

+ 174 - 149
resources/views/user/index.blade.php

@@ -63,23 +63,19 @@
                                 <span class="font-weight-400">{{trans('user.account.remain')}}</span>
                                 <div class="text-center font-weight-100 font-size-40">
                                     {{$unusedTraffic}}
-                                    <br>
+                                    <br/>
                                     <h4>{{trans('user.account.level')}}:<code class="font-size-20">{{Auth::user()->level}}</code></h4>
                                 </div>
                                 <div class="text-center font-weight-300 blue-grey-500 mb-10">
                                     @if(isset($resetDays) && $resetDays >= 0)
-                                        {{trans('user.account.reset', ['days' => $resetDays])}}
+                                        {!! trans_choice('user.account.reset',$resetDays, ['days' => $resetDays]) !!}
                                     @endif
                                 </div>
                             </div>
                             <div class="col-lg-5 col-md-12 col-sm-5">
-                                <div class="w-only-xs-p50 w-only-sm-p75 w-only-md-p50" data-plugin="pieProgress"
-                                     data-valuemax="100"
-                                     data-barcolor="#96A3FA" data-size="100" data-barsize="10"
-                                     data-goal="{{$unusedPercent}}" aria-valuenow="{{$unusedPercent}}"
-                                     role="progressbar">
-                                    <span class="pie-progress-number blue-grey-700 font-size-20">
-                                        {{$unusedPercent}}%</span>
+                                <div class="w-only-xs-p50 w-only-sm-p75 w-only-md-p50" data-plugin="pieProgress" data-valuemax="100" data-barcolor="#96A3FA" data-size="100"
+                                     data-barsize="10" data-goal="{{$unusedPercent}}" aria-valuenow="{{$unusedPercent}}" role="progressbar">
+                                    <span class="pie-progress-number blue-grey-700 font-size-20">{{$unusedPercent}}%</span>
                                 </div>
                             </div>
                         </div>
@@ -171,7 +167,7 @@
                                                     <option value="surge">Surge</option>
                                                     <option value="shadowrocket">Shadowrocket</option>
                                                     <option value="v2rayn">v2rayN</option>
-                                                    {{--                                                    <option value="shadowsocks">SS路由器</option>--}}
+                                                    {{-- <option value="shadowsocks">SS路由器</option> --}}
                                                 </select>
                                             </div>
                                         </div>
@@ -200,6 +196,15 @@
                             </div>
                         </div>
                     </div>
+                    <div class="col-xl-4 mb-30">
+                        <div class="card card-shadow text-center h-full">
+                            <div class="card-block">
+                                <h4 class="card-title"><i class="wb-bell mr-10 yellow-600"></i>{{trans('user.home.chat_group')}}</h4>
+                                <a class="card-link btn btn-lg btn-primary" href="https://t.me/+nW8AwsPPUsliYzg1" target="_blank" rel="noopener">
+                                    Telegram {{trans('user.home.chat_group')}} <i class="fa-brands fa-telegram"></i></a>
+                            </div>
+                        </div>
+                    </div>
                 </div>
                 <div class="row" data-plugin="matchHeight" data-by-row="true">
                     <div class="col-xxl-6 mb-30">
@@ -291,156 +296,176 @@
     {{--        </script>--}}
     {{--    @endif--}}
     <script>
-        // 更换订阅地址
-        function exchangeSubscribe() {
-            swal.fire({
-                title: '{{trans('common.warning')}}',
-                text: '{{trans('user.subscribe.exchange_warning')}}',
-                icon: 'warning',
-                showCancelButton: true,
-                cancelButtonText: '{{trans('common.close')}}',
-                confirmButtonText: '{{trans('common.confirm')}}',
-            }).then((result) => {
-                if (result.value) {
-                    $.post('{{route('changeSub')}}', {_token: '{{csrf_token()}}'}, function(ret) {
-                        if (ret.status === 'success') {
-                            swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
-                        } else {
-                            swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
-                        }
-                    });
-                }
-            });
-        }
-
-        const clipboard = new ClipboardJS('.mt-clipboard', {
-            text: function(trigger) {
-                let base = @json($subUrl);
-                const client = $('#client').val();
-                const subType = $('#subType').val();
-                if (subType && client) {
-                    base += '?target=' + client + '&type=' + subType;
-                } else if (subType) {
-                    base += '?type=' + subType;
-                } else if (client) {
-                    base += '?target=' + client;
-                }
-                return base;
-            },
-        });
-        clipboard.on('success', function() {
-            swal.fire({
-                title: '{{trans('common.copy.success')}}',
-                icon: 'success',
-                timer: 1300,
-                showConfirmButton: false,
+      function exchangeSubscribe() { // 更换订阅地址
+        swal.fire({
+          title: '{{trans('common.warning')}}',
+          text: '{{trans('user.subscribe.exchange_warning')}}',
+          icon: 'warning',
+          showCancelButton: true,
+          cancelButtonText: '{{trans('common.close')}}',
+          confirmButtonText: '{{trans('common.confirm')}}',
+        }).then((result) => {
+          if (result.value) {
+            $.post('{{route('changeSub')}}', {_token: '{{csrf_token()}}'}, function(ret) {
+              if (ret.status === 'success') {
+                swal.fire({title: ret.message, icon: 'success', timer: 1000, showConfirmButton: false}).then(() => window.location.reload());
+              } else {
+                swal.fire({title: ret.message, icon: 'error'}).then(() => window.location.reload());
+              }
             });
+          }
         });
-        clipboard.on('error', function() {
-            swal.fire({
-                title: '{{trans('common.copy.failed')}}',
-                icon: 'error',
-                timer: 1500,
-                showConfirmButton: false,
-            });
+      }
+
+      const clipboard = new ClipboardJS('.mt-clipboard', {
+        text: function(trigger) {
+          let base = @json($subUrl);
+          const client = $('#client').val();
+          const subType = $('#subType').val();
+          if (subType && client) {
+            base += '?target=' + client + '&type=' + subType;
+          } else if (subType) {
+            base += '?type=' + subType;
+          } else if (client) {
+            base += '?target=' + client;
+          }
+          return base;
+        },
+      });
+      clipboard.on('success', function() {
+        swal.fire({
+          title: '{{trans('common.copy.success')}}',
+          icon: 'success',
+          timer: 1300,
+          showConfirmButton: false,
         });
+      });
+      clipboard.on('error', function() {
+        swal.fire({
+          title: '{{trans('common.copy.failed')}}',
+          icon: 'error',
+          timer: 1500,
+          showConfirmButton: false,
 
-        // 签到
-        function checkIn() {
-            $.post('{{route('checkIn')}}', {_token: '{{csrf_token()}}'}, function(ret) {
-                if (ret.status === 'success') {
-                    swal.fire(ret.title, ret.message, 'success');
-                } else {
-                    swal.fire(ret.title, ret.message, 'error');
-                }
-            });
-        }
+        });
+      });
 
-        function common_options(tail) {
-            return {
-                responsive: true,
-                scales: {
-                    x: {
-                        ticks: {
-                            callback: function(value) {
-                                return this.getLabelForValue(value) + tail;
-                            },
-                        },
-                        grid: {
-                            display: false,
-                        },
-                    },
-                    y: {
-                        ticks: {
-                            callback: function(value) {
-                                return this.getLabelForValue(value) + ' GB';
-                            },
-                        },
-                        grid: {
-                            display: false,
-                        },
-                        min: 0,
-                    },
+      @if(sysConfig('is_checkin'))
+      function checkIn() { // 签到
+        $.post('{{route('checkIn')}}', {_token: '{{csrf_token()}}'}, function(ret) {
+          if (ret.status === 'success') {
+            swal.fire(ret.title, ret.message, 'success');
+          } else {
+            swal.fire(ret.title, ret.message, 'error');
+          }
+        });
+      }
+      @endif
 
+      function common_options(tail) {
+        return {
+          responsive: true,
+          scales: {
+            x: {
+              ticks: {
+                callback: function(value) {
+                  return this.getLabelForValue(value) + tail;
                 },
-                plugins: {
-                    legend: false,
-                    tooltip: {
-                        mode: 'index',
-                        intersect: false,
-                        callbacks: {
-                            title: function(context) {
-                                return context[0].label + tail;
-                            },
-                            label: function(context) {
-                                return context.parsed.y + ' GB';
-                            },
-                        },
-                    },
+              },
+              grid: {
+                display: false,
+              },
+            },
+            y: {
+              ticks: {
+                callback: function(value) {
+                  return this.getLabelForValue(value) + ' GB';
                 },
-            };
-        }
+              },
+              grid: {
+                display: false,
+              },
+              min: 0,
+            },
+          },
+          plugins: {
+            legend: false,
+            tooltip: {
+              mode: 'index',
+              intersect: false,
+              callbacks: {
+                title: function(context) {
+                  return context[0].label + tail;
+                },
+                label: function(context) {
+                  return context.parsed.y + ' GB';
+                },
+              },
+            },
+          },
+        };
+      }
 
-        function datasets(label, data) {
-            return {
-                labels: label,
-                datasets: [
-                    {
-                        backgroundColor: 'rgba(184, 215, 255)',
-                        borderColor: 'rgba(184, 215, 255)',
-                        data: data,
-                        tension: 0.4,
-                    }],
-            };
-        }
+      function datasets(label, data) {
+        return {
+          labels: label,
+          datasets: [
+            {
+              backgroundColor: 'rgba(184, 215, 255)',
+              borderColor: 'rgba(184, 215, 255)',
+              data: data,
+              tension: 0.4,
+            }],
+        };
+      }
 
-        new Chart(document.getElementById('dailyChart'), {
-            type: 'line',
-            data: datasets(@json($dayHours), @json($trafficHourly)),
-            options: common_options(' {{trans_choice('validation.attributes.hour', 2)}}'),
-        });
+      new Chart(document.getElementById('dailyChart'), {
+        type: 'line',
+        data: datasets(@json($dayHours), @json($trafficHourly)),
+        options: common_options(' {{trans_choice('validation.attributes.hour', 2)}}'),
+      });
 
-        new Chart(document.getElementById('monthlyChart'), {
-            type: 'line',
-            data: datasets(@json($monthDays), @json($trafficDaily)),
-            options: common_options(' {{trans_choice('validation.attributes.day', 2)}}'),
-        });
+      new Chart(document.getElementById('monthlyChart'), {
+        type: 'line',
+        data: datasets(@json($monthDays), @json($trafficDaily)),
+        options: common_options(' {{trans_choice('validation.attributes.day', 2)}}'),
+      });
 
-        @if($banedTime)
-        // 每秒更新计时器
-        const countDownDate = new Date("{{$banedTime}}").getTime();
-        const x = setInterval(function() {
-            const distance = countDownDate - new Date().getTime();
-            const hours = Math.floor(distance % 86400000 / 3600000);
-            const minutes = Math.floor((distance % 3600000) / 60000);
-            const seconds = Math.floor((distance % 60000) / 1000);
-            document.getElementById('countdown').innerHTML = hours + '{{trans_choice('validation.attributes.hour', 1)}} ' + minutes
-                + '{{trans('validation.attributes.minute')}} ' + seconds + '{{trans('validation.attributes.second')}}';
-            if (distance <= 0) {
-                clearInterval(x);
-                document.getElementById('countdown').remove();
-            }
-        }, 1000);
-        @endif
+      @if($banedTime) // 封禁倒计时
+      const banedTime = new Date("{{$banedTime}}").getTime();
+      countDown(banedTime, 'banedTime', true);
+      setInterval(function() {
+        countDown(banedTime, 'banedTime', true);
+      }, 1000);
+      @endif
+
+      @if(isset($resetDays) && $resetDays === 0) // 重置日倒计时
+      const resetTime = new Date("{{date("Y-m-d 00:00", strtotime("tomorrow"))}}").getTime();
+      countDown(resetTime, 'restTime');
+      setInterval(function() {
+        countDown(resetTime, 'restTime');
+      }, 60000);
+      @endif
+
+      function countDown(endTime, id, seconds = false) { // 计时器主题逻辑
+        const distance = endTime - new Date().getTime();
+        const hour = Math.floor(distance % 86400000 / 3600000);
+        const minute = Math.floor((distance % 3600000) / 60000);
+        let string = '';
+        if (hour) {
+          string += hour + '{{ trans_choice('validation.attributes.hour', 1) }} ';
+        }
+        if (minute) {
+          string += minute + '{{ trans('validation.attributes.minute') }}';
+        }
+        if (seconds) {
+          string += ' ' + Math.floor((distance % 60000) / 1000) + '{{trans('validation.attributes.second')}}';
+        }
+        document.getElementById(id).innerHTML = string;
+
+        if (distance <= 0) {
+          window.location.reload();
+        }
+      }
     </script>
 @endsection