root 4 years ago
parent
commit
4d5c54a283
100 changed files with 9253 additions and 5 deletions
  1. 20 4
      .gitignore
  2. 1 0
      MP_verify_Vouqz8661wUWLa5t.txt
  3. 1 1
      README.md
  4. 15 0
      apidoc.json
  5. 335 0
      app/Console/Commands/ActiveUser.php
  6. 86 0
      app/Console/Commands/ActivitiesStats.php
  7. 116 0
      app/Console/Commands/AsyncUserSign.php
  8. 225 0
      app/Console/Commands/AutoSendTrusteeShipCustomerMsg.php
  9. 72 0
      app/Console/Commands/AutoWithdrawCash.php
  10. 57 0
      app/Console/Commands/BillTask.php
  11. 118 0
      app/Console/Commands/Book/BookAutoOffShelf.php
  12. 155 0
      app/Console/Commands/Book/BookRechargePredict.php
  13. 114 0
      app/Console/Commands/Book/ChapterRetentionRate.php
  14. 145 0
      app/Console/Commands/Book/FreeBookStats.php
  15. 143 0
      app/Console/Commands/Book/NewBookTestData.php
  16. 85 0
      app/Console/Commands/Book/NewBookTestUserDetail.php
  17. 69 0
      app/Console/Commands/Book/bookChargeStats.php
  18. 73 0
      app/Console/Commands/BookAdjust.php
  19. 62 0
      app/Console/Commands/BookAdjustOne.php
  20. 196 0
      app/Console/Commands/BookAfterSpider.php
  21. 168 0
      app/Console/Commands/BookAttr.php
  22. 72 0
      app/Console/Commands/BookGiftStats/BookGiftStatsByBook.php
  23. 74 0
      app/Console/Commands/BookGiftStats/BookGiftStatsByGift.php
  24. 91 0
      app/Console/Commands/BookSearchInfoStat.php
  25. 210 0
      app/Console/Commands/BookUpdate.php
  26. 257 0
      app/Console/Commands/BookUpdateOne.php
  27. 136 0
      app/Console/Commands/BusinessChannelStatTask.php
  28. 56 0
      app/Console/Commands/CP/GenerateCpBookBetweenStat.php
  29. 49 0
      app/Console/Commands/CP/GenerateCpBookStat.php
  30. 52 0
      app/Console/Commands/CP/fixCpBookStat.php
  31. 54 0
      app/Console/Commands/ChangePay.php
  32. 74 0
      app/Console/Commands/Channel/CheckStatus.php
  33. 70 0
      app/Console/Commands/Channel/SiteTitle.php
  34. 72 0
      app/Console/Commands/ChannelReaderVisitStats.php
  35. 66 0
      app/Console/Commands/ChapterImageTask.php
  36. 146 0
      app/Console/Commands/ChapterOrderTotal.php
  37. 47 0
      app/Console/Commands/CheckAndSend.php
  38. 104 0
      app/Console/Commands/CheckBookCover.php
  39. 47 0
      app/Console/Commands/CheckOfficialAccountTemplate.php
  40. 88 0
      app/Console/Commands/CheckZsySiteStatus.php
  41. 46 0
      app/Console/Commands/CpcAdvertise/AutoWithdraw.php
  42. 52 0
      app/Console/Commands/CpcAdvertise/CpcBillTasks.php
  43. 48 0
      app/Console/Commands/CpcAdvertise/MonthlyStatsTasks.php
  44. 94 0
      app/Console/Commands/CustomMsg/CustomMsgStrategyAutoSend.php
  45. 46 0
      app/Console/Commands/CustomSignPush.php
  46. 46 0
      app/Console/Commands/CustomSubscribePush.php
  47. 61 0
      app/Console/Commands/DistributionStats/WeeklyDailyStats.php
  48. 59 0
      app/Console/Commands/DownPic.php
  49. 214 0
      app/Console/Commands/FailOrderAlert.php
  50. 161 0
      app/Console/Commands/FailOrderAlertV2.php
  51. 48 0
      app/Console/Commands/ForBiddenOfficialAccountRemind.php
  52. 263 0
      app/Console/Commands/ForceUserActive.php
  53. 148 0
      app/Console/Commands/ForceUserActiveDetail.php
  54. 108 0
      app/Console/Commands/IndividualOpPlatform/AddDeepReadRecords.php
  55. 33 0
      app/Console/Commands/Inspire.php
  56. 119 0
      app/Console/Commands/LatestCustomerMsg.php
  57. 46 0
      app/Console/Commands/NoPayRemind.php
  58. 71 0
      app/Console/Commands/OfficialAccountBillsTask.php
  59. 86 0
      app/Console/Commands/OfficialAccountStat/OfficialAccountForbiddenStatus.php
  60. 214 0
      app/Console/Commands/OfficialAccountStat/SubUserRecharge.php
  61. 47 0
      app/Console/Commands/PaidUserRemind.php
  62. 85 0
      app/Console/Commands/PaymentQueryTask.php
  63. 62 0
      app/Console/Commands/PaymentStatisticTask.php
  64. 51 0
      app/Console/Commands/ProductStats/DailyProductionStats.php
  65. 49 0
      app/Console/Commands/ProductStats/MonthlyProductionStats.php
  66. 116 0
      app/Console/Commands/ProductStats/SendDailyNewProductionStats.php
  67. 98 0
      app/Console/Commands/ProductStats/SendDailyProductionStats.php
  68. 76 0
      app/Console/Commands/ProductStats/SendMonthStatsEmail.php
  69. 68 0
      app/Console/Commands/ProductStats/SendMonthlyProductStats.php
  70. 86 0
      app/Console/Commands/ReadRecordPersistence.php
  71. 47 0
      app/Console/Commands/RecoverPush.php
  72. 76 0
      app/Console/Commands/RepeatBookOrderRecover.php
  73. 80 0
      app/Console/Commands/SendOrder/GenerateBookUvRegisterStat.php
  74. 68 0
      app/Console/Commands/SendOrder/GenerateDayByBooksStat.php
  75. 115 0
      app/Console/Commands/SendOrder/GenerateForceDayStat.php
  76. 51 0
      app/Console/Commands/SendOrder/GenerateStat.php
  77. 205 0
      app/Console/Commands/SendOrder/GenerateUserRegistStat.php
  78. 156 0
      app/Console/Commands/SendOrder/SendOrderSendOrderPvUv.php
  79. 177 0
      app/Console/Commands/SendOrder/SendStatsEmail.php
  80. 188 0
      app/Console/Commands/SendOrder/SetExtraStats.php
  81. 62 0
      app/Console/Commands/SendOrder/StatSendOrderByDate.php
  82. 93 0
      app/Console/Commands/SendOrder/UpdateSendOrderPreSendDate.php
  83. 84 0
      app/Console/Commands/SendOrder/UserActivityStats.php
  84. 59 0
      app/Console/Commands/SendOrderBreakevenForceUser.php
  85. 53 0
      app/Console/Commands/SendServiceMsg.php
  86. 133 0
      app/Console/Commands/SignReward.php
  87. 47 0
      app/Console/Commands/SmartPush/AllPushHotBook.php
  88. 47 0
      app/Console/Commands/SmartPush/LongChapterCustom.php
  89. 48 0
      app/Console/Commands/SmartPush/LongChapterTemplate.php
  90. 47 0
      app/Console/Commands/SmartPush/PaidPushPointBook.php
  91. 47 0
      app/Console/Commands/SmartPush/PaidUserCustom.php
  92. 47 0
      app/Console/Commands/SmartPush/UnPaidPushHotBook.php
  93. 47 0
      app/Console/Commands/SmartPush/UnPaidPushPointBook.php
  94. 46 0
      app/Console/Commands/SmartPush/UnPaidUserBigActivity.php
  95. 46 0
      app/Console/Commands/SmartPush/UnPaidUserSmallActivity.php
  96. 138 0
      app/Console/Commands/SmartPush/UpdateMediaPushRechargeInfo.php
  97. 84 0
      app/Console/Commands/SmartPush/UpdateRecommandBooks.php
  98. 123 0
      app/Console/Commands/SubscribeAlert.php
  99. 117 0
      app/Console/Commands/SubscribeDataStats.php
  100. 0 0
      app/Console/Commands/SuperiorBooks/DailyScanForSupriorNewBook.php

+ 20 - 4
.gitignore

@@ -1,6 +1,22 @@
-# ---> Laravel
-/bootstrap/compiled.php
-.env.*.php
-.env.php
+/vendor
+/node_modules
+Homestead.yaml
+Homestead.json
+/idea
 .env
+/storage/app
+/storage/framework
+/storage/logs
+composer.lock
+/public/log/
+.buildpath
+.project
+.settings
+.DS_Store
+.idea
+.idea/
 
+public/log.txt
+public/wxpay/pay*
+public/wxpay/channel*
+public/wxpay/zsyyd*

+ 1 - 0
MP_verify_Vouqz8661wUWLa5t.txt

@@ -0,0 +1 @@
+Vouqz8661wUWLa5t

+ 1 - 1
README.md

@@ -1,2 +1,2 @@
-# wangdu_public_api
+# wangdu_modify_public_api
 

+ 15 - 0
apidoc.json

@@ -0,0 +1,15 @@
+{
+"name": "阅读云公共平台接口",
+"version": "1.0.0",
+"description": "阅读云公共平台接口",
+"title": "阅读云公共平台接口",
+"url": "test.manage.zhuishuyun.com/api/",
+"template": {
+"withCompare": true,
+"withGenerator": true
+},
+"header": {
+    "title": "概述",
+    "filename": "header.md"
+  }
+}

+ 335 - 0
app/Console/Commands/ActiveUser.php

@@ -0,0 +1,335 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Carbon\Carbon;
+use DB;
+use Redis;
+
+class ActiveUser extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'au';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $appids = $this->getAppids();
+        if(!$appids) return ;
+        foreach ($appids as $appid) {
+            $this->getUser($appid);
+        }
+    }
+
+    //获取appid
+    private function getAppids():array
+    {
+        //return ['wxb9fe767d99513216'];
+        $data = [];
+        $appids = DB::table('media_push_gzhs')->where('is_enabled',1)->select('appid')->get();
+        if(!$appids) return $data;
+        foreach ($appids as $appid_info){
+            $data[] = $appid_info->appid;
+        }
+        return $data;
+    }
+
+    private function getUser($appid)
+    {
+        $count = DB::table('force_subscribe_users')->where('appid', $appid)->where('is_subscribed', 1)->count();
+        //echo '$count is:' . $count . PHP_EOL;
+        //echo ' ceil($count/1000) is:' . ceil($count / 1000) . PHP_EOL;
+        for ($i = 0, $c = ceil($count / 1000); $i < $c; $i++) {
+            //echo 'now is the ' . $i . 'times' . PHP_EOL;
+            $result = DB::table('force_subscribe_users')
+                ->select('uid', 'distribution_channel_id', 'appid', 'openid', 'subscribe_time', 'last_interactive_time')
+                ->orderBy('created_at', 'desc')
+                ->offset($i * 1000)->limit(1000)->get();
+            if (!$result)
+                break;
+            //echo 'foreach start' . PHP_EOL;
+            foreach ($result as $v) {
+                $temp_time = 0;
+                //签到时间
+                $sign = DB::table('smart_push_user_sign')->where('uid', $v->uid)->where('day', Carbon::yesterday()->format('Y-m-d'))->select('sign_time')->first();
+                if ($sign) $temp_time = $sign->sign_time;
+                //阅读时间
+                $read_record = Redis::hget('book_read:' . $v->uid, 'last_read');
+                if ($read_record) {
+                    $arr = explode('_', $read_record);
+                    $read_time = isset($arr[2]) ? $arr[2] : 0;
+                    $temp_time = $read_time > $temp_time ? $read_time : $temp_time;
+                }
+                //交互时间
+                $last_interactive_time = Carbon::createFromFormat('Y-m-d H:i:s', $v->last_interactive_time)->timestamp;
+                if ($last_interactive_time > Carbon::yesterday()->timestamp) {
+                    $temp_time = $last_interactive_time > $temp_time ? $last_interactive_time : $temp_time;
+                }
+
+                if (!$temp_time || $temp_time < Carbon::yesterday()->timestamp) continue;
+                $hour = Carbon::createFromTimestamp($temp_time)->hour;
+                if ($hour >= 22 || $hour <= 6) {
+                    $hour = 10;
+                }
+                $result = $this->updateOrCreateMediaPushUser($v->uid, $v->openid, $v->distribution_channel_id, $v->appid, $hour, $v->subscribe_time);
+                $pay_info = DB::table('orders')->where('uid', $v->uid)->where('status', 'PAID')->orderBy('id')->first();
+                $now = Carbon::now();
+                $days_num_in_month = $now->daysInMonth;
+                //这个月剩余天数
+                $last_days = $days_num_in_month - $now->day + 1;
+                if (Carbon::createFromFormat('Y-m-d H:i:s', $v->subscribe_time)->format('Y-m-d') == Carbon::yesterday()->format('Y-m-d')) {
+                    //关注
+                    if ($pay_info) {
+                        //echo 'paid $uid is: ' . $v->uid . '----------------------------------------' . PHP_EOL;
+                        //已经付费
+                        $o = DB::table('media_push_user_details')->where('media_push_user_id', $result[0])->where('created_at', '>=', date('Y-m-d 00:00:00'))->count();
+                        //echo '$o is ' . $o . ',----------------' . PHP_EOL;
+                        if (!$o) {
+                            $days = $this->selectDay($last_days, 4, Carbon::createFromFormat('Y-m-d H:i:s', $v->last_interactive_time)->addDay(2));
+                            $this->updateOrCreateMediaPushUserDetail($v->uid, $result[0], $days);
+                        }
+                    } else {
+                        //echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' . PHP_EOL;
+                        //echo 'no pay $uid is: ' . $v->uid . '----------------------------------------' . PHP_EOL;
+                        //未付费
+                        if ($last_days > 8) {
+                            $num = ceil($last_days / 2);
+                        } else {
+                            $num = $last_days;
+                        }
+                        $o = DB::table('media_push_user_details')->where('media_push_user_id', $result[0])->where('created_at', '>=', date('Y-m-d 00:00:00'))->count();
+                        if (!$o) {
+                            $days = $this->selectDay($num, 4, Carbon::createFromFormat('Y-m-d H:i:s', $v->last_interactive_time)->addDay(2));
+
+                            $this->updateOrCreateMediaPushUserDetail($v->uid, $result[0], $days);
+                        }
+                    }
+                } else {
+                    //非当日强关
+                    if ($pay_info && date('Y-m-d', strtotime($pay_info->created_at)) == date('Y-m-d', time() - 86400)) {
+                        //echo 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,$uid is :' . $v->uid . PHP_EOL;
+                        //充值了
+                        $old = DB::table('media_push_user_details')->where('uid', $v->uid)->where('created_at', '>=', date('Y-m-d 00:00:00'))->count();
+                        $all = DB::table('media_push_user_details')->where('uid', $v->uid)->where('created_at', '>=', date('Y-m-01 00:00:00'))->count();
+                        $one = DB::table('media_push_user_details')->where('uid', $v->uid)->where('created_at', '>=', date('Y-m-01 00:00:00'))->first();
+                        //echo sprintf('$old is: %s,$all is: %s,%s',$old,$all,PHP_EOL);
+                        //print_r($one);
+                        if ($all && $old) {
+                            $days = $this->selectDay($last_days, $old, $now);
+                            foreach ($days as $k => $vd) {
+                                DB::table('media_push_user_details')
+                                    ->where('media_push_user_id', $one->media_push_user_id)
+                                    ->where('sort_no', $all - $old + $k + 1)
+                                    ->update(['updated_at' => date('Y-m-d H:i:s'), 'send_time' => $vd]);
+                            }
+                        }
+                    } else {
+                        if ($last_days > 8) {
+                            $num = ceil($last_days / 2);
+                        } else {
+                            $num = $last_days;
+                        }
+                        //echo 'ddddddddddddddddddddddddddddddddddddddd' . PHP_EOL;
+                        $days = $this->selectDay($num, 4, $now);
+                        $this->updateOrCreateMediaPushUserDetail($v->uid, $result[0], $days, 'old');
+                    }
+
+                }
+            }
+        }
+    }
+
+    private function updateOrCreateMediaPushUser($uid, $openid, $distribution_channel_id, $appid, $active_hour, $sub_time)
+    {
+        $old = DB::table('media_push_users')->where('uid', $uid)->where('openid', $openid)->select('id')->first();
+        $updated_at = Carbon::now()->format('Y-m-d H:i:s');
+        $created_at = $updated_at;
+        if ($old) {
+            $id = $old->id;
+            $type = 'update';
+            DB::table('media_push_users')->where('id', $old->id)->update(compact('active_hour', 'updated_at'));
+        } else {
+            $id = DB::table('media_push_users')->insertGetId(
+                compact('uid', 'openid', 'distribution_channel_id', 'appid', 'active_hour', 'sub_time', 'created_at', 'updated_at')
+            );
+            $type = 'create';
+        }
+        return [$id, $type];
+    }
+
+    private function updateOrCreateMediaPushUserDetail($uid, $media_push_user_id, $days, $type = 'new')
+    {
+        if (!$days) return;
+
+        $data = [];
+        if ($type == 'new') {
+            foreach ($days as $k => $d) {
+                $data[] = ['media_push_user_id' => $media_push_user_id, 'uid' => $uid, 'is_send' => 0, 'sort_no' => $k + 1, 'send_time' => $d, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()];
+            }
+            DB::table('media_push_user_details')->insert($data);
+        }
+        if ($type == 'old') {
+            $o = DB::table('media_push_user_details')->where('uid', $uid)->where('created_at', '>=', date('Y-m-01 00:00:00'))->count();
+            if (!$o) {
+                foreach ($days as $k => $d) {
+                    $data[] = ['media_push_user_id' => $media_push_user_id, 'uid' => $uid, 'is_send' => 0, 'sort_no' => $k + 1, 'send_time' => $d, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()];
+                }
+                DB::table('media_push_user_details')->insert($data);
+            }
+        }
+
+        if ($type == 'update') {
+
+        }
+    }
+
+    /**
+     * @param int $uid
+     * @param bool $is_charge 是否充值
+     * @return array
+     */
+    private function getFourDate(int $uid, bool $is_charge, int $count = 4)
+    {
+        $now = Carbon::now();
+        $days_num_in_month = $now->daysInMonth;
+        //这个月剩余天数
+        $last_days = $days_num_in_month - $now->day + 1;
+
+        $num = 10;
+        return $this->selectDay($num, $count, $now);
+    }
+
+    private function selectDay(int $alldays, int $selectCount = 4, $start_day):array
+    {
+        $start_day = $start_day->format('Y-m-d');
+        //echo '$alldays is :' . $alldays . '--$selectCount is :' . $selectCount . '--$start_day is: ' . $start_day . PHP_EOL;
+        $days = [];
+        $month = Carbon::now()->month;
+        for ($i = 0; $i < $alldays; $i++) {
+            $temp_timestamp = strtotime($start_day) + $i * 86400;
+            $temp = date('Y-m-d', $temp_timestamp);
+            if (date('n', $temp_timestamp) != $month) {
+                break;
+            }
+            $days[] = $temp;
+        }
+
+        if (empty($days) || count($days) <= $selectCount) return $days;
+        $result = [];
+        $c = 0;
+        $saturdays = [];
+        foreach ($days as $key => $v) {
+            if (date('N', strtotime($v)) == 6) {
+                $saturdays[] = $key;
+                array_push($result, $v);
+                if (++$c == $selectCount) return $result;
+            }
+        }
+        $rate = (count($days) - 1) / $selectCount;
+        $temp_count = 0;
+        $temp_count2 = 0;
+        for ($k = 0, $d = count($days); $k < $d; $k++) {
+            $temp_count2++;
+            $temp = $k + $rate * ($k);
+            $key = round($temp);
+            $key = $key < 0 ? 0 : $key;
+            if (!isset($days[$key]) || count($result) >= $selectCount) {
+                break;
+            }
+            if (isset($saturdays[$temp_count])) {
+                if (abs($saturdays[$temp_count] - $temp) >= $rate * 0.8) {
+                    $result[] = $days[$key];
+                    if ($key >= $saturdays[$temp_count]) {
+                        $temp_count++;
+                    }
+                } else {
+                    continue;
+                }
+            } else {
+                $result[] = $days[$key];
+                if (isset($saturdays[$temp_count]) && $key >= $saturdays[$temp_count]) {
+                    $temp_count++;
+                }
+            }
+        }
+        usort($result, function ($a, $b) {
+            return strtotime($a) >= strtotime($b);
+        });
+        $result_count = count($result);
+        if ($result_count < $selectCount) {
+            $start = $days[0];
+            $end = $days[count($days) - 1];
+            $last = [];
+            for ($i = 0; $i <= $result_count; $i++) {
+                if ($i == 0) {
+                    $last[] = strtotime($result[$i]) - strtotime($start);
+                    continue;
+                }
+                if ($i == $result_count) {
+                    $last[] = strtotime($end) - strtotime($result[$i - 1]);
+                    continue;
+                }
+
+                $last[] = strtotime($result[$i]) - strtotime($result[$i - 1]);
+            }
+            if ($last) {
+                $max = max($last);
+                $max_key = [];
+                foreach ($last as $lk => $l) {
+                    if ($max == $l) {
+                        $max_key[] = $lk;
+                    }
+                }
+                $other_key = array_random($max_key);
+                if ($other_key > $result_count) {
+                    array_push($result, date('Y-m-d', strtotime($result[$result_count - 1]) + $max / 2));
+                } else if ($other_key == 0) {
+                    array_push($result, date('Y-m-d', strtotime($start) + $max / 2));
+                } else {
+                    array_push($result, date('Y-m-d', strtotime($result[$other_key - 1]) + $max / 2));
+                }
+            }
+            usort($result, function ($a, $b) {
+                return strtotime($a) >= strtotime($b);
+            });
+        }
+        return $result;
+    }
+
+    private function test()
+    {
+        $result = $this->selectDay(4, 4, Carbon::now());
+        echo "---------------------------------------------------\r\n";
+        if ($result) {
+            foreach ($result as $v) {
+                echo $v . PHP_EOL;
+            }
+        }
+    }
+}

+ 86 - 0
app/Console/Commands/ActivitiesStats.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Activity\Models\ActivityStatistic;
+use App\Modules\Channel\Models\Channel;
+use App\Modules\Finance\Models\CommissionRate;
+use App\Modules\Trade\Services\OrderService;
+use DB;
+use GuzzleHttp\Client;
+use Illuminate\Console\Command;
+
+class ActivitiesStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'generateActivitiesStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '活动数据生成';
+
+
+    public function handle()
+    {
+        $activities = \DB::table('activity')
+            ->whereIn('distribution_channel_id',[0])
+            ->where('end_time','<=',date('Y-m-d H:i:s'))
+            ->where('stats_created',0)
+            ->get();
+        foreach ($activities as $key=>$activity) {
+            $start_time = $activity->start_time;
+            $end_time = $activity->end_time;
+            $channels = Channel::getAllChannels();
+            foreach ($channels as $channel){
+                $activity_stats = \DB::table('activity_statistic')
+                        ->where('activity_id',$activity->id)
+                        ->where('distribution_channel_id',$channel->id)
+                        ->where('daily_stats_created',1)
+                        ->first();
+                if(!$activity_stats) {
+                    $stats = \DB::table('orders')
+                        ->where('activity_id',$activity->id)
+                        ->where('distribution_channel_id',$channel->id)
+                        ->whereBetween('created_at',[$start_time,$end_time])
+                        ->where('status','PAID')
+                        ->select(\DB::raw("sum(price) as recharge_amount,count(*) as success_order_num"))
+                        ->first();
+
+                    $orders_count = \DB::table('orders')
+                        ->where('distribution_channel_id',$channel->id)
+                        ->where('activity_id',$activity->id)
+                        ->whereBetween('created_at',[$start_time,$end_time])
+                        //->where('status','PAID')
+                        ->count('id');
+
+                    $insert = ['activity_id'=>$activity->id,'distribution_channel_id'=>$channel->id];
+                    $update = [
+                        'recharge_amount'=>$stats->recharge_amount,
+                        'success_order_num'=>$stats->success_order_num,
+                        'order_num'=>$orders_count,
+                        'promotion_stats_created'=>1,
+                        'daily_stats_created'=>1
+                    ];
+                    if($stats->recharge_amount>0){
+                        ActivityStatistic::updateOrCreate($insert,$update);
+                    }
+                }
+
+            }
+            \DB::table('activity')->where('id',$activity->id)->update(['stats_created'=>1]);
+        }
+    }
+
+    static public function getUserClient()
+    {
+        return new Client(['base_uri' => env('AUTH_API_BASE_URI')]);
+    }
+
+}

+ 116 - 0
app/Console/Commands/AsyncUserSign.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\OfficialAccountService;
+use App\Modules\Finance\Services\WithdrawCashService;
+use App\Modules\User\Models\UserSign;
+use App\Modules\User\Models\TempsUserSign;
+use App\Modules\User\Models\SmartPushUserSign;
+use App\Modules\OfficialAccount\Models\DistributionSelfDefineConfig;
+use App\Modules\Finance\Services\FinancialStatService;
+use Redis;
+
+/**
+ * 签到user_sign异步批量插入
+ * @author zhoulingjie
+ *
+ */
+class AsyncUserSign extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'AsyncUserSign';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '签到user_sign异步批量插入';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+    public function start(){
+    	\Log::info('AsyncUserSign_start');
+    	// 获取redis里面的所有数据
+    	$uids = Redis::smembers('user_sign:uid');
+    	$loop_num = 100;
+    	$loop_current = 0;
+    	if(!empty($uids)){
+    		//\Log::info('AsyncUserSign_start_count:'.count($uids));
+    		$batch_insert_data = [];
+    		foreach($uids as $uid){
+    			try{
+    				$loop_current ++;
+    				
+    				$insert_data = [];
+    				 
+    				$sign_data = Redis::hget('user_sign:uid:info',$uid);
+    				$sign_data = object_to_array(json_decode($sign_data));
+    				//\Log::info('AsyncUserSign_loop_current:'.$loop_current.' uid:'.$uid.' data:'.json_encode($sign_data));
+    				if(!empty($sign_data)){
+    					$batch_insert_data[] = $sign_data;
+    					Redis::srem('user_sign:uid',$uid);
+    					Redis::hdel('user_sign:uid:info',$uid);
+    				}
+    				if($loop_current == $loop_num){
+//    					\Log::info('$batch_insert_data');
+//    					\Log::info($batch_insert_data);
+
+    					self::batch_sign_insert($batch_insert_data);
+    					$batch_insert_data = [];
+    					$loop_current = 0;
+    				}
+    			}catch(\Exception $e){
+	    			\Log::info('AsyncUserSign_ept:'.$e->getMessage());
+	    		}
+    		}
+    		
+    		// last
+    		\Log::info('$last_batch_insert_data');
+    		\Log::info($batch_insert_data);
+    		self::batch_sign_insert($batch_insert_data);
+    
+    	}
+
+    	\Log::info('AsyncUserSign_end:'.count($uids));
+    }
+    
+    public static function batch_sign_insert($batch_insert_data){
+    	if(!empty($batch_insert_data)){
+            $model = new UserSign();
+            $model->setCurrentTable(date('Ym'));
+            $model->insert($batch_insert_data);
+            $model->setCurrentTable( date('Ym',strtotime('next Month')) );
+            $model->insert($batch_insert_data);
+    		//UserSign::insert($batch_insert_data);
+    		// 中间表,保留2个月数据
+//     		TempsUserSign::insert($batch_insert_data);
+    		// 智能推送表,保留2天数据
+    		SmartPushUserSign::insert($batch_insert_data);
+    	}
+    }
+}

+ 225 - 0
app/Console/Commands/AutoSendTrusteeShipCustomerMsg.php

@@ -0,0 +1,225 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\BatchCustomMsgService;
+use App\Modules\Book\Services\BookConfigService;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+use App\Modules\OfficialAccount\Services\OfficialAccountService;
+use App\Modules\OfficialAccount\Models\CustomMsgSendTimeConfig;
+use DB;
+class AutoSendTrusteeShipCustomerMsg extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'AutoSendTrusteeShipCustomerMsg';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '自动推送托管客服消息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+
+    private $hour_begin;
+    private $hour_end;
+
+    public function handle()
+    {
+        $this->hour_begin = date('H:00:00');
+        $this->hour_end = date('H:59:59');
+        $batch_no =  '默认批次';
+        //所有开启推送的渠道
+        $all_channel_ids = DB::table('custom_msg_switchs_msgs')
+            ->where('status',1)
+            ->where('custom_category','auto_custom_trusteeship')
+            ->select(DB::raw("distinct distribution_channel_id as unique_distribution_channel_id"))
+            ->pluck('unique_distribution_channel_id')
+            ->toArray();
+
+        //自定义时间的渠道
+        $customize_time_channel_ids = CustomMsgSendTimeConfig::where('is_enable',1)
+            ->where('custom_category','auto_custom_trusteeship')
+            ->whereIn('distribution_channel_id',$all_channel_ids)
+            ->select(DB::raw("distinct distribution_channel_id as unique_distribution_channel_id"))
+            ->pluck('unique_distribution_channel_id')
+            ->toArray();
+
+        //获取没有自定义发送时间的站点19点统一发送
+        if($this->hour_begin == '19:00:00'){
+            //判断今天是否已经发送过
+            $today_send_status = DB::table('batch_custom_send_msgs')
+                ->where('send_time','>',date('Y-m-d'))
+                ->where('name','like','%'.$batch_no.'%')
+                ->first();
+            if(!$today_send_status){
+
+                //需要跑的站点=  所有开启推送的站点 - 自定义时间的站点
+                $channel_ids = array_diff($all_channel_ids,$customize_time_channel_ids);
+                dump($batch_no);
+                $this->autoSendTrusteeShipCustomerMsg($channel_ids,$batch_no);
+            }
+
+        }
+
+        //获取有自定义发送时间且在一小时内需要创建的站点
+        $channel_ids = CustomMsgSendTimeConfig::where('is_enable',1)
+            ->where('custom_category','auto_custom_trusteeship')
+            ->whereBetween('send_time',[$this->hour_begin,$this->hour_end])
+            ->whereIn('distribution_channel_id',$all_channel_ids)
+            ->where(function ($query) {
+                $query->where('last_send_date','<',date('Y-m-d'))
+                    ->orWhereNull('last_send_date');
+            })
+            ->select(DB::raw("distinct distribution_channel_id as unique_distribution_channel_id"))
+            ->pluck('unique_distribution_channel_id')
+            ->toArray();
+        $batch_no ='自定义批次';
+        dump($batch_no);
+         $this->autoSendTrusteeShipCustomerMsg($channel_ids,$batch_no);
+    }
+
+
+    /**
+     * 创建客服消息
+     */
+    public function autoSendTrusteeShipCustomerMsg($channel_ids,$batch_no = '')
+    {
+        \Log::info('autoSendTrusteeShipCustomerMsg:');
+        $sexs = ['a', 'b'];
+        $customMsgPrams['send_time'] = date('Y-m-d H:00:00');
+        $customMsgPrams['redirect_url'] = '';
+        $customMsgPrams['subscribe_time'] = 'g';// 关注1天前,有过交互的
+        $customMsgPrams['trusteeship'] = '1'; // 托管
+        $customMsgPrams['balance'] = 'z';
+        $customMsgPrams['order_type'] = 'z';
+        $customMsgPrams['category_id'] = 'z';
+        $customMsgPrams['status'] = '1';
+        $customMsgPrams['is_show_list'] = '0';// 分销界面不展示
+        $batch_name = $batch_no;
+        //设置书籍标题的站点
+        $book_title_channel_ids = DB::table('custom_msg_switchs_msgs')
+            ->where('status',1)
+            ->where('custom_category','auto_custom_trusteeship')
+            ->where('title_type','BOOK')
+            ->select(DB::raw("distinct distribution_channel_id as unique_distribution_channel_id"))
+            ->pluck('unique_distribution_channel_id')
+            ->toArray();
+        //
+        dump('需要跑的站点');
+        dump($channel_ids);
+        dump('设置书籍标题的站点');
+        dump($book_title_channel_ids);
+        //带书名标题的站点
+        dump('需要跑的设置书籍标题的站点');
+        $book_title_channels = array_intersect($channel_ids,$book_title_channel_ids);
+        dump($book_title_channels);
+        dump('需要跑的带系统标题的站点');
+        //带系统标题的站点
+        $default_title_channels = array_diff($channel_ids,$book_title_channels);
+        dump($default_title_channels);
+        //带默认标题
+        if ($default_title_channels) {
+            dump('带系统标题');
+            foreach ($sexs as $sex) {
+                $customMsgPrams['content'] = $this->getMsgContent($sex, 'SYS');
+                $customMsgPrams['sex'] = $sex;
+                $customMsgPrams['name'] = '自动发送托管客服消息_系统标题'.date('YmdH').$batch_name;
+                \Log::info($customMsgPrams);
+                $batch_res = BatchCustomMsgService::addBatchCustomSendMsgs($customMsgPrams, $batch_no);
+                if ($batch_res == 1) {
+                    //创建客服消息
+                    $this->BatchCreateCustomSendMsgs($customMsgPrams,$default_title_channels,$batch_no);
+                }
+            }
+        }
+        //带书名标题
+        if ($book_title_channels) {
+            dump('带书名标题');
+            foreach ($sexs as $sex) {
+                $customMsgPrams['content'] = $this->getMsgContent($sex, 'BOOK');
+                $customMsgPrams['sex'] = $sex;
+                $customMsgPrams['name'] = '自动发送托管客服消息_书名标题'.date('YmdH').$batch_name;
+                \Log::info($customMsgPrams);
+                $batch_res = BatchCustomMsgService::addBatchCustomSendMsgs($customMsgPrams,$batch_no);
+                \Log::info('batch_res:' . $batch_res . ' batch_no:' . $batch_no);
+                if ($batch_res == 1) {
+                    //创建客服消息
+                    $this->BatchCreateCustomSendMsgs($customMsgPrams,$book_title_channels,$batch_no);
+                }
+            }
+        }
+
+    }
+
+
+    public function getMsgContent($sex,$title_type='')
+    {
+        // 男生
+        if($sex == 'a'){
+            $books = BookConfigService::getTrusteeShipChannelBook('','男频', 4);
+        }
+        // 女生
+        else{
+            $books = BookConfigService::getTrusteeShipChannelBook('','女频', 4);
+        }
+        $books = CustomMsgService::get_book_full_infos($books,$sex,$title_type);
+        return json_encode($books);
+    }
+
+    public function BatchCreateCustomSendMsgs($customMsgPrams,$in_channel_ids=[],$batch_no=''){
+        $customMsgPrams['batch_no'] = $batch_no;
+        //按站点取其下公众号创建摸板消息
+        foreach($in_channel_ids as $channel_id){
+            $time_config = CustomMsgSendTimeConfig::getTimeConfig($channel_id,[
+                'begin_time'=>$this->hour_begin,
+                'end_time'=>$this->hour_end,
+            'custom_category'=>'auto_custom_trusteeship',
+            ]);
+            if($time_config){
+                $customMsgPrams['send_time']=date('Y-m-d').' '.$time_config->send_time;
+                $time_config->last_send_date =date('Y-m-d');
+                $time_config->save();
+            }
+
+            $officialAccountParams['in_channle_ids'] = [$channel_id];
+            $official_accounts =  OfficialAccountService::getTrusteeshipOfficialAccountsWithParams($officialAccountParams);
+            \Log::info($official_accounts);
+            $customMsgPrams['distribution_channel_id'] = $channel_id;
+            foreach($official_accounts as $official_account){
+                $customMsgPrams['appid'] = $official_account->appid;
+                \Log::info('getTrusteeshipOfficialAccounts:appid:'.$official_account->appid.' distribution_channel_id:'.$channel_id);
+                //先判断在发送时间段1小时以内,有没有发起过相同的模板消息,如果有发送过,就提示用户已经创建过相同模板消息,不创建新的模板消息
+                $isSendCustomer = CustomMsgService::isSendCustomerAtSameTimeAndSex($customMsgPrams);
+                if (!empty($isSendCustomer)) {
+                    \Log::info('isSendCustomerAtSameTime already_send:appid:'.$customMsgPrams['appid'].' distribution_channel_id:'.$customMsgPrams['distribution_channel_id']);
+                    continue;
+                }
+                $customMsgService = CustomMsgService::addCustomSendMsgs($customMsgPrams);
+
+            }
+        }
+
+    }
+
+}

+ 72 - 0
app/Console/Commands/AutoWithdrawCash.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\OfficialAccountService;
+use App\Modules\Finance\Services\WithdrawCashService;
+use App\Modules\OfficialAccount\Models\DistributionSelfDefineConfig;
+use App\Modules\Finance\Services\FinancialStatService;
+
+class AutoWithdrawCash extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'AutoWithdrawCash';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '自动申请提现';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+    public function start(){
+    	\Log::info('auto_withdraw_cash_start');
+    	// 获取自动提现的渠道列表
+    	$distributionSelfDefineConfigs = DistributionSelfDefineConfig::getDistributionsByType('auto_withdraw_cash');
+    	foreach($distributionSelfDefineConfigs as $distributionSelfDefineConfig){
+    		try{
+    			$distribution_channel_id = $distributionSelfDefineConfig->distribution_channel_id;
+    			\Log::info('auto_withdraw_start:'.$distribution_channel_id);
+    			$financialStat = FinancialStatService::getFinancialStatSingle($distribution_channel_id);
+    			\Log::info($financialStat);
+    			if($financialStat['enable_withdrawal_amount'] >= 100){
+    				$amount = intval(($financialStat['enable_withdrawal_amount']*100))/100;
+    				\Log::info('real_amount:'.$amount.' orgin_amount:'.$financialStat['enable_withdrawal_amount']);
+    				$res = WithdrawCashService::auto_add_withdrawCash($distribution_channel_id,$amount,'系统自动申请提现');
+    				\Log::info('auto_withdraw:'.json_encode($res,JSON_UNESCAPED_UNICODE));
+    			}else{
+    				\Log::info('auto_withdraw_not_enough:'.$distribution_channel_id.' amount:'.$financialStat['enable_withdrawal_amount']);
+    			}
+    		}catch(Exception $e){
+    			\Log::info('auto_withdraw_cash_ept:'.$e->getMessage());
+    		}
+    		
+    	}
+    	\Log::info('auto_withdraw_cash_end');
+    }
+}

+ 57 - 0
app/Console/Commands/BillTask.php

@@ -0,0 +1,57 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands;
+
+use App\Modules\Channel\Services\ChannelService;
+use App\Modules\Finance\Models\BillPayMerchant;
+use App\Modules\Finance\Services\BillPayMerchantService;
+use App\Modules\Finance\Services\BillService;
+use App\Modules\Finance\Services\FinanceService;
+use Log;
+use Illuminate\Console\Command;
+
+class BillTask extends Command
+{
+    /**
+     * 执行命令   php artisan bill_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'bill_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日生成结算单生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日生成结算单生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======每日生成结算单生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        FinanceService::makeDayDataStatistics();
+        Log::info("======每日生成结算单生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======每日生成结算单生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+
+    private function updateBranchAccount() {
+        $channels = ChannelService::getAllChannels();
+        foreach ($channels as $channel) {
+            BillPayMerchant::where('distribution_channel');
+        }
+    }
+}

+ 118 - 0
app/Console/Commands/Book/BookAutoOffShelf.php

@@ -0,0 +1,118 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: z-yang
+ * Date: 2020/10/29
+ * Time: 9:49
+ */
+
+namespace App\Console\Commands\Book;
+
+use DB;
+use Illuminate\Console\Command;
+use App\Modules\Message\MessageNotify;
+
+class BookAutoOffShelf extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'Book:BookAutoOffShelf';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '自动下架';
+
+    private $emails = ['zhaojp@yqsd.net',
+        'songdb@yqsd.net','zhoulj@iqiyoo.com'
+    ];
+    //private $emails = ['zhaoy@zw88.net','baixq@zw88.net'];
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle(){
+        $this->start();
+    }
+
+
+    private function start(){
+        $day = date('Y-m-d',time()+86400*10);
+        $book = DB::table('book_configs')->where('is_on_shelf',2)
+            ->where('copyright_limit_data','<=',$day)
+            ->where('copyright_limit_data','>=',date('Y-m-d'))
+            ->select('bid','book_name','copyright_limit_data')
+            ->get();
+        $off_shelf_book = [];
+        $alert_book = [];
+        if($book){
+            foreach ($book as $item){
+                if($item->copyright_limit_data <= date('Y-m-d')){
+                    $off_shelf_book[] = ['bid'=>$item->bid,'book_name'=>$item->book_name];
+                }
+                if($item->copyright_limit_data == $day){
+                    $alert_book[] = ['bid'=>$item->bid,'book_name'=>$item->book_name];
+                }
+            }
+        }
+
+        //《陆先生的情之所至》将于2020.10.29日下架,请尽快确认!
+        if($alert_book){
+            $content = '';
+            foreach ($alert_book as $item_book){
+                $content .= sprintf('<p>《%s》将于%s日下架,请尽快确认!</p>',$item_book['book_name'],$day);
+            }
+            $this->warning('[网读]书籍下架提醒',$content);
+        }
+        if($off_shelf_book){
+            $to_insert = [];
+            $bid = [];
+            foreach ($off_shelf_book as $item){
+                $bid[] = $item['bid'];
+                $to_insert[] = [
+                    'bid' => $item['bid'],'book_name'=>$item['book_name'],'channel_name'=>'',
+                    'update_date' => date('Y-m-d'),'update_chapter_count'=>2,'update_words'=>1,
+                    'update_type' => 'onshelfstatus','operator'=>'command-Book:BookAutoOffShelf',
+                    'created_at' => date('Y-m-d H:i:s'),
+                    'updated_at' => date('Y-m-d H:i:s')
+                ];
+
+            }
+            DB::table('book_updates')->insert($to_insert);
+            DB::table('book_configs')->whereIn('bid',$bid)->update([
+                'is_on_shelf'=>4,'updated_at'=>date('Y-m-d H:i:s')
+            ]);
+        }
+    }
+
+
+
+    private function warning($subject,$msg){
+
+        $notify = MessageNotify::mail([
+            'to_emails' => implode(",", $this->emails),
+            'subject' => $subject,
+            'body' =>$msg,
+            'delay_times' => 0,
+        ]);
+        $notify->notify();
+        return ;
+    }
+
+}

+ 155 - 0
app/Console/Commands/Book/BookRechargePredict.php

@@ -0,0 +1,155 @@
+<?php
+
+namespace App\Console\Commands\Book;
+
+use Illuminate\Console\Command;
+use App\Modules\Book\Models\Chapter;
+use App\Modules\Book\Models\Book;
+use App\Modules\Book\Models\BookConfig;
+use App\Modules\Book\Models\BookRechargeExpectedPositions;
+
+class BookRechargePredict extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book_recharge_predict';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '书籍充值预测';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        $params = array(
+            ['first_recharge_amount'=>50,'first_recharge_bookcoin'=>9000,'secondChargeAmount'=>50,'second_recharge_bookcoin'=>9000],
+            ['first_recharge_amount'=>50,'first_recharge_bookcoin'=>9000,'secondChargeAmount'=>30,'second_recharge_bookcoin'=>3000],
+            ['first_recharge_amount'=>30,'first_recharge_bookcoin'=>3000,'secondChargeAmount'=>50,'second_recharge_bookcoin'=>9000],
+            ['first_recharge_amount'=>30,'first_recharge_bookcoin'=>3000,'secondChargeAmount'=>30,'second_recharge_bookcoin'=>3000],
+        );
+        $books = BookConfig::whereIn('is_on_shelf',[1,2])->get();
+        foreach ($books as $book){
+            if($book->charge_type == 'BOOK'){
+                continue;
+            }
+            foreach ($params as $param){
+                //dump($book->name);
+                $this->simulationDeduction($book,$param);
+            }
+        }
+    }
+
+    public function simulationDeduction($book,$param){
+        $price_rate = 0.04;//默认4毛
+        echo('千字价位为:'.$price_rate);
+        $give_bookcoin = 80;
+        $prediction = array();
+        $prediction['bid'] = $book->bid;
+        $seq=$book->vip_seq;
+        $blance = 0;
+        $prediction['first_recharge_amount'] = $param['first_recharge_amount'];
+        $blance += $param['first_recharge_bookcoin'] + $give_bookcoin;
+        $prediction['balance_after_first_recharge'] = $blance;
+        //dump('首充金额:'.$prediction['first_recharge_amount'].'首充后余额:'.$blance.'首充章节'.$seq);
+        while($blance>0) {
+            $chapter = Chapter::getChapterByBidAndSeq($book->bid, $seq);
+            if ($chapter) {
+                $price = $this->getPrice($chapter,$price_rate);
+                $real_fee = $chapter->size*$price_rate;
+                if($price>$blance){break;}
+                $blance -= $price;
+                //dump("第{$seq}章节,共{$chapter->size}字数,应收{$real_fee},实际收费{$price},扣费后余额为{$blance}");
+                $seq++;
+            } else {
+                break;
+            }
+        }
+
+        if($chapter){
+            $prediction['sec_chapter_id'] = $chapter->id;
+            $prediction['sec_chapter_seq'] = $chapter->sequence;
+            $prediction['sec_chapter_name'] = $chapter->name;
+            $prediction['balance_before_sec_recharge'] = $blance;
+            $prediction['sec_recharge_amount'] = $param['secondChargeAmount'];
+            $blance += $param['second_recharge_bookcoin'] + $give_bookcoin;
+            $prediction['balance_after_sec_recharge'] = $blance;
+            //dump('二充金额:'.$prediction['sec_recharge_amount'].'二充前余额:'.$prediction['balance_before_sec_recharge'].'二充后余额:'.$blance.'二充章节'.$seq);
+            while($blance>0) {
+                $chapter = Chapter::getChapterByBidAndSeq($book->bid, $seq);
+                if ($chapter) {
+                    $price = $this->getPrice($chapter,$price_rate);
+                    $real_fee = $chapter->size*$price_rate;
+                    if($price>$blance){break;}
+                    $blance -= $price;
+                    //dump("第{$seq}章节,共{$chapter->size}字数,应收{$real_fee},实际收费{$price},扣费后余额为{$blance}");
+                    $seq++;
+                } else {
+                    break;
+                }
+            }
+
+            if($chapter){
+                $prediction['third_chapter_id'] = $chapter->id;
+                $prediction['third_chapter_seq'] = $chapter->sequence;
+                $prediction['third_chapter_name'] = $chapter->name;
+                $prediction['balance_before_third_recharge'] = $blance;
+            }else{
+                $prediction['third_chapter_id'] = '';
+                $prediction['third_chapter_seq'] = '';
+                $prediction['third_chapter_name'] = '';
+                $prediction['balance_before_third_recharge'] = '';
+            }
+            //dump('三充前余额:'.$prediction['balance_before_third_recharge'].'二充章节'.$seq);
+        }else{
+            $prediction['sec_chapter_id'] = '';
+            $prediction['sec_chapter_seq'] = '';
+            $prediction['sec_chapter_name'] = '';
+            $prediction['balance_after_first_recharge'] = '';
+            $prediction['balance_before_sec_recharge'] = '';
+            $prediction['sec_recharge_amount'] = '';
+            $prediction['third_chapter_id'] = '';
+            $prediction['third_chapter_seq'] = '';
+            $prediction['third_chapter_name'] = '';
+            $prediction['balance_after_sec_recharge'] = '';
+            $prediction['balance_before_third_recharge'] = '';
+        }
+
+        BookRechargeExpectedPositions::updateOrCreate([
+            'bid'=>$prediction['bid'],
+            'first_recharge_amount'=>$prediction['first_recharge_amount'],
+            'sec_recharge_amount'=>$prediction['sec_recharge_amount'],
+            ]
+            ,$prediction);
+
+    }
+
+    public static function getPrice($chapter,$price_rate){
+
+        $fee = ceil($chapter->size * $price_rate);
+        if($fee >189) $fee = 189;
+        if($fee <37) $fee = 37;
+
+        return $fee;
+    }
+}
+

+ 114 - 0
app/Console/Commands/Book/ChapterRetentionRate.php

@@ -0,0 +1,114 @@
+<?php
+
+namespace App\Console\Commands\Book;
+
+use App\Modules\Book\Models\Book;
+use App\Modules\Book\Models\BookCategory;
+use App\Modules\Book\Models\BookConfig;
+use App\Modules\Book\Models\RententionBookList;
+use App\Modules\Book\Services\RententionBookService;
+use Illuminate\Console\Command;
+use Log;
+
+/**
+ * 章节留存率
+ */
+class ChapterRetentionRate extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'calc_chapter_retention_rate {--is_init=} {--is_all=} {--bid=} {--begin_bid=} {--end_bid=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '计算章节留存率';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======计算章节留存率 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======计算章节留存率 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        $is_all = $this->option('is_all');
+        $is_init = $this->option('is_init');
+        if ($is_init) {
+            $bids = RententionBookList::where('sex', 2)->pluck('bid')->all();
+            foreach ($bids as $bid) {
+                RententionBookService::saveRententionBook($bid);
+            }
+        } else if ($is_all) {
+            $bids = $this->findAllRunBooks();
+            foreach ($bids as $bid) {
+                $this->runBook($bid);
+            }
+        } else {
+            $bid = $this->option('bid');
+            $begin_bid = $this->option('begin_bid');
+            $end_bid = $this->option('end_bid');
+            if ($begin_bid) {
+                $bids = Book::where('id', '>=', $begin_bid)
+                    ->where('id', '<', $end_bid)
+                    ->orderBy('id', 'desc')
+                    ->pluck('id')
+                    ->all();
+                foreach ($bids as $bid) {
+                    $this->runBook($bid);
+                }
+            } else {
+                $this->runBook($bid);
+            }
+        }
+
+        Log::info("======计算章节留存率 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======计算章节留存率 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+    }
+
+    public function findAllRunBooks()
+    {
+        $catetory_ids = BookCategory::where('pid', 2)->pluck('id')->all();
+        $new_bids = Book::where('created_at', '>=', date('Y-m-d', strtotime('-3 months')))
+            ->whereIn('category_id', $catetory_ids)
+            ->pluck('id')->all();
+        $bids = BookConfig::whereIn('bid', $new_bids)->whereIn('is_on_shelf', [1, 2])->pluck('bid')->all();
+        $rentention_bids =  RententionBookList::join('book_configs', 'book_configs.bid', 'rentention_book_list.bid')
+            ->where([
+                'is_updated' => 1,
+            ])->where('type', '!=', RententionBookService::BelowStandard)
+            ->where('sex', 2)
+            ->whereIn('is_on_shelf', [1, 2])
+            ->pluck('rentention_book_list.bid')->all();
+        return array_merge(
+            $rentention_bids,
+            $bids
+        );
+    }
+
+
+    public function runBook(int $bid)
+    {
+        myLog('rentention_book')->info('bid: ' . $bid . ' begin: ' . date('Y-m-d H:i:s'));
+        RententionBookService::runRentention($bid);
+        RententionBookService::saveRententionBook($bid);
+        myLog('rentention_book')->info('bid: ' . $bid . ' end: ' . date('Y-m-d H:i:s'));
+    }
+}

+ 145 - 0
app/Console/Commands/Book/FreeBookStats.php

@@ -0,0 +1,145 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: z-yang
+ * Date: 2020/8/25
+ * Time: 19:06
+ */
+
+namespace App\Console\Commands\Book;
+
+use Illuminate\Console\Command;
+use Redis;
+use DB;
+
+class FreeBookStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:FreeBookStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '限免图书统计';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle(){
+        $day  = date('Y-m-d',time()-86400);
+        $this->numStats($day);//人数统计
+        $this->wapVirtualStats($day);
+        $this->wapChargeStats($day);
+    }
+
+
+    private function wapVirtualStats($day){
+        $virtual_keys = Redis::SMEMBERS('wap:free:virtual'.$day);;
+        if(!$virtual_keys) return ;
+        $data = [];
+        $i = 0;
+        foreach ($virtual_keys as $id){
+            $fee = Redis::hget('book:free:virtual:'.$id,$day);
+            $data[] = ['free_book_config_id'=>$id,'type'=>'WAP','day'=>$day,
+                'virtual_fee'=>$fee,'charge_amount'=>0,
+                'created_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')];
+            $i++;
+            if($i % 100 == 0){
+                DB::table('free_book_stats')->insert($data);
+                $data = [];
+            }
+            Redis::hdel('book:free:virtual:'.$id,$day);
+            DB::table('free_books')->where('id',$id)->update(['virtual_fee'=>DB::raw('virtual_fee+'.$fee)]);
+        }
+        if($data) DB::table('free_book_stats')->insert($data);
+        Redis::del('wap:free:virtual'.$day);
+    }
+
+    private function wapChargeStats($day){
+        $charge_keys = Redis::SMEMBERS('wap:free:charge'.$day);;
+        if(!$charge_keys) return ;
+        $data = [];
+        $i = 0;
+        foreach ($charge_keys as $id){
+            $charge = Redis::hget('book:free:charge:'.$id,$day);
+            if($charge){
+                $charge = $charge/100;
+            }
+            $data[] = ['free_book_config_id'=>$id,'type'=>'WAP','day'=>$day,
+                'virtual_fee'=>0,'charge_amount'=>$charge,
+                'created_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')];
+            $i++;
+            if($i % 100 == 0){
+                DB::table('free_book_stats')->insert($data);
+                $data = [];
+            }
+            Redis::hdel('book:free:charge:'.$id,$day);
+            DB::table('free_books')->where('id',$id)->update(['charge_amount'=>DB::raw('charge_amount+'.$charge)]);
+        }
+        if($data) DB::table('free_book_stats')->insert($data);
+        Redis::del('wap:free:charge'.$day);
+    }
+    private function numStats($day){
+        $options = [
+            [
+                'key_prefix'    =>'wap:free:virtual',
+                'varname'       =>'virtual_num',
+                'type'          =>'WAP',
+            ],
+            [
+                'key_prefix'    =>'wap:free:charge',
+                'varname'       =>'charge_num',
+                'type'          =>'WAP',
+            ],
+        ];
+        foreach ($options as $option){
+            $res = Redis::SMEMBERS($option['key_prefix'].$day);;
+            if(!$res) return ;
+            $data = [];
+            $i = 0;
+            foreach ($res as $id){
+                $key = $option['key_prefix'].':uids'.$day.$id;
+                $uids = Redis::SMEMBERS($key);
+                if(!$uids)continue;
+                $num = count($uids);
+
+                $tem_data = ['free_book_config_id'=>$id,'type'=>$option['type'],'day'=>$day,
+                    'virtual_fee'=>0,
+                    'charge_amount'=>0,
+                    'charge_num'=>0,
+                    'virtual_num'=>0,
+                    'created_at'=>date('Y-m-d H:i:s'),
+                    'updated_at'=>date('Y-m-d H:i:s')];
+                $tem_data[$option['varname']] = $num;
+                $data[] = $tem_data;
+                $i++;
+                if($i % 100 == 0){
+                    DB::table('free_book_stats')->insert($data);
+                    $data = [];
+                }
+                DB::table('free_books')->where('id',$id)->update([$option['varname']=>DB::raw($option['varname'].'+'.$num)]);
+                Redis::del($key);
+            }
+            if($data) DB::table('free_book_stats')->insert($data);
+            //Redis::del($option['key_prefix'].$day);
+        }
+    }
+
+}

+ 143 - 0
app/Console/Commands/Book/NewBookTestData.php

@@ -0,0 +1,143 @@
+<?php
+
+namespace App\Console\Commands\Book;
+
+use Illuminate\Console\Command;
+
+use App\Modules\Statistic\Services\WapVisitStatService;
+use DB;
+
+
+
+class NewBookTestData extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'new_book_test_data';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '新书测试数据填充';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->oneDayDataFill();
+        $this->threeDayDataFill();
+        $this->sixDayDataFill();
+        $this->sevenDayDataFill();
+
+
+    }
+    function oneDayDataFill(){
+        $one_day_before = date('Y-m-d H:i:s',strtotime('-1 day'));
+
+        $new_book_tests = DB::table('new_book_tests')
+            ->where('test_end_time','<=',$one_day_before)
+//            ->where('status',2)
+            ->whereNull('uv_in_one_day')
+            ->whereNull('sub_amount_in_one_day')
+            ->get();
+        if(!$new_book_tests){return;}
+
+        foreach ($new_book_tests as $item) {
+            $data = array();
+            $book_statistics = WapVisitStatService::smartPushTestBookStats($item->bid);
+            $data['uv_in_one_day'] = $book_statistics['uv'];
+            $data['sub_amount_in_one_day'] = $book_statistics['book_amount'];
+            DB::table('new_book_tests')
+                ->where('id',$item->id)
+                ->update($data);
+
+        }
+    }
+    function threeDayDataFill(){
+        $three_day_before = date('Y-m-d H:i:s',strtotime('-3 day'));
+        $new_book_tests = DB::table('new_book_tests')
+            ->where('test_end_time','<=',$three_day_before)
+//            ->where('status',2)
+            ->whereNull('uv_in_three_day')
+            ->whereNull('sub_amount_in_three_day')
+            ->get();
+        if(!$new_book_tests){return;}
+
+        foreach ($new_book_tests as $item) {
+            $data = array();
+            $book_statistics = WapVisitStatService::smartPushTestBookStats($item->bid);
+            $data['uv_in_three_day'] = $book_statistics['uv'];
+            $data['sub_amount_in_three_day'] = $book_statistics['book_amount'];
+            DB::table('new_book_tests')
+                ->where('id',$item->id)
+                ->update($data);
+
+        }
+    }
+
+    function sevenDayDataFill(){
+        $seven_day_before = date('Y-m-d H:i:s',strtotime('-7 day'));
+        $seven_day_before_limit = date('Y-m-d H:i:s',strtotime('-7 day -1hour'));
+
+        $new_book_tests = DB::table('new_book_tests')
+            ->where('test_end_time','<=',$seven_day_before)
+            ->where('test_end_time','>=',$seven_day_before_limit)
+            ->whereNull('uv_in_seven_day')
+            ->whereNull('sub_amount_in_seven_day')
+            ->get();
+
+        if(!$new_book_tests){return;}
+
+        foreach ($new_book_tests as $item) {
+            $data = array();
+            $book_statistics = WapVisitStatService::smartPushTestBookStats($item->bid);
+            $data['uv_in_seven_day'] = $book_statistics['uv'];
+            $data['sub_amount_in_seven_day'] = $book_statistics['book_amount'];
+            DB::table('new_book_tests')
+                ->where('id',$item->id)
+                ->update($data);
+
+        }
+    }
+
+    function sixDayDataFill(){
+        $six_day_before = date('Y-m-d H:i:s',strtotime('-6 day'));
+        $six_day_before_limit = date('Y-m-d H:i:s',strtotime('-6 day -1hour'));
+        $new_book_tests = DB::table('new_book_tests')
+            ->where('test_end_time','<=',$six_day_before)
+            ->where('test_end_time','>=',$six_day_before_limit)
+            ->whereNull('uv_in_six_day')
+            ->whereNull('sub_amount_in_six_day')
+            ->get();
+        if(!$new_book_tests){return;}
+
+        foreach ($new_book_tests as $item) {
+            $data = array();
+            $book_statistics = WapVisitStatService::smartPushTestBookStats($item->bid);
+            $data['uv_in_six_day'] = $book_statistics['uv'];
+            $data['sub_amount_in_six_day'] = $book_statistics['book_amount'];
+            DB::table('new_book_tests')
+                ->where('id',$item->id)
+                ->update($data);
+
+        }
+    }
+}
+

+ 85 - 0
app/Console/Commands/Book/NewBookTestUserDetail.php

@@ -0,0 +1,85 @@
+<?php
+
+namespace App\Console\Commands\Book;
+use Illuminate\Console\Command;
+use DB;
+use Redis;
+
+class NewBookTestUserDetail extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'new_book_test_user_detail';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '新书测试用户数据';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        $new_book_test_ids = DB::table('new_book_tests')
+            ->leftjoin('new_book_test_users','new_book_test_users.test_id','new_book_tests.id')
+            ->whereNotNull('new_book_tests.test_end_time')
+            ->where('new_book_tests.status',2)
+            ->whereNull('new_book_test_users.test_id')
+            ->select('new_book_tests.*')
+            ->get()
+            ->pluck('id')
+            ->toArray();
+        if(!$new_book_test_ids){return;}
+
+        foreach ($new_book_test_ids as $new_book_test_id){
+            $this->getNewBookTestUserData($new_book_test_id);
+        }
+    }
+
+    /**
+     * 获取新书测试用户数据
+     * @param $new_book_test_id
+     */
+    public static function getNewBookTestUserData($new_book_test_id){
+        if(!$new_book_test_id)return [];
+
+        $key ='NewBookTestUserDetail:'.$new_book_test_id;
+        $count = Redis::ZCARD($key);
+        $member_list = Redis::ZRANGE($key,0,$count);
+        $insert_data = array();
+
+        foreach ($member_list as $index=>$member){
+            $data = array();
+            $score = Redis::ZSCORE($key,$member);
+            $data['uid'] = $member;
+            $data['push_time'] = date('Y-m-d H:i:s',$score);
+            $data['test_id'] = $new_book_test_id;
+            $insert_data[] = $data;
+            if(count($insert_data)>=1000){
+
+                DB::table('new_book_test_users')->insert($insert_data);
+                $insert_data = array();
+            }
+        }
+        DB::table('new_book_test_users')->insert($insert_data);
+    }
+}
+

+ 69 - 0
app/Console/Commands/Book/bookChargeStats.php

@@ -0,0 +1,69 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: z-yang
+ * Date: 2020/10/21
+ * Time: 11:05
+ */
+
+namespace App\Console\Commands\Book;
+
+use DB;
+use Redis;
+use Illuminate\Console\Command;
+
+class bookChargeStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'bookChargeStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '书籍充值统计';
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle(){
+        $day = date('Y-m-d',time()-86400);
+        $this->start($day);
+    }
+
+
+    private function start($day){
+        $max_bid_info = DB::table('books')->select('id')->orderBy('id','desc')->first();
+        $max_bid = $max_bid_info->id;
+        $data = [];
+        for($i = 1;$i <= $max_bid;$i++){
+            $amount = Redis::hget('book:charge:stats:'.$day,$i);
+            if(!$amount) continue;
+            $data[] = ['bid'=>$i,'day'=>$day,'amount'=>$amount,'created_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')];
+            if(count($data) % 100 == 0){
+                DB::table('book_charge_statistical')->insert($data);
+                $data = [];
+            }
+        }
+        if($data){
+            DB::table('book_charge_statistical')->insert($data);
+        }
+        Redis::del('book:charge:stats:'.$day);
+    }
+}

+ 73 - 0
app/Console/Commands/BookAdjust.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\Book\Models\Chapter;
+use App\Modules\Book\Models\Book;
+class BookAdjust extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:adjust';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '调整所有章节顺序prev_cid和next_cid';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->adjustSequentAll();
+        return  1;
+    }
+
+    /**
+     * 调整所有顺序
+     */
+    public function adjustSequentAll(){
+        set_time_limit(0);
+
+        Book::where('last_cid','!=',0)->where('id','>=',807)->select('id')->get()->map(function ($item, $key){
+            $this->adjustSequentOne($item->id);
+        });
+    }
+
+    /**
+     * 调整单本书的顺序
+     * @param $bid
+     */
+    public function adjustSequentOne($bid){
+        $chapter_list = Chapter::getChapterLists($bid);
+        $prev = 0;
+
+        foreach ($chapter_list as $chapter){
+            if($prev){
+                Chapter::where('id',$chapter->id)->update(['prev_cid'=>$prev]);
+                Chapter::where('id',$prev)->update(['next_cid'=>$chapter->id]);
+            }
+            $prev = $chapter->id;
+        }
+
+    }
+}

+ 62 - 0
app/Console/Commands/BookAdjustOne.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+class BookAdjustOne extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:adjustone {--bid= : the id of a book}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '调整所有章节顺序prev_cid和next_cid';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $bid = $this->option('bid');
+        if(empty($bid)) return 0;
+        $this->adjustSequentOne($bid);
+    }
+
+    /**
+     * 调整单本书的顺序
+     * @param $bid
+     */
+    public function adjustSequentOne($bid){
+        $chapter_list = DB::table('chapters')->orderBy('sequence')->where('bid',$bid)->get();
+        $prev = 0;
+
+        foreach ($chapter_list as $chapter){
+            if($prev){
+                DB::table('chapters')->where('id',$chapter->id)->update(['prev_cid'=>$prev]);
+                DB::table('chapters')->where('id',$prev)->update(['next_cid'=>$chapter->id]);
+            }
+            $prev = $chapter->id;
+        }
+
+    }
+}

+ 196 - 0
app/Console/Commands/BookAfterSpider.php

@@ -0,0 +1,196 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Book\Services\ChapterService;
+use Illuminate\Console\Command;
+use App\Modules\Product\Services\ProductService;
+use App\Modules\Book\Models\BookConfig;
+use GuzzleHttp\Client;
+use DB;
+use App\Modules\Book\Services\BookConfigService;
+
+class BookAfterSpider extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:afs {bid*} {--scope}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '采集之后';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+     private $update_info = [];
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $all_bid = $this->argument('bid');
+        $options = $this->option('scope');
+        if ($options) {
+            $bids = DB::table('books')->where('id', '>=', $all_bid[0])->select('id')->get();
+            foreach ($bids as $key => $value) {
+                $this->starts($value->id);
+            }
+        } else {
+            foreach ($all_bid as $key => $value) {
+                $this->starts($value);
+            }
+        }
+        $this->recordUpdateInfo();
+    }
+
+    private function starts($bid)
+    {
+        $this->addbookConfig($bid);
+        $this->bookChapterInfo($bid);
+        $this->adjustSequentOne($bid);
+        //ChapterService::splitContentAll($bid);
+    }
+
+    private function addproducts()
+    {
+        $res = ProductService::addProduct([
+            'price' => '8.99',
+            'type' => 'BOOK_ORDER',
+            'given' => 0,
+            'is_default' => 0,
+            'is_enabled' => 1,
+            'sequence' => 0
+        ]);
+        return $res->id;
+    }
+
+    private function addbookConfig($bid)
+    {
+        $sql = "UPDATE books set intro = REPLACE(intro,'&nbsp;','') where id = " . $bid;
+        DB::update($sql);
+        $book_info = DB::table('books')->where('id', $bid)->first();
+        $book_config = DB::table('book_configs')->where('bid', $bid)->first();
+        if ($book_config) {
+            if ($book_info->ly_bid) {
+                $cp = $this->getcp($book_info->ly_bid);
+                DB::table('book_configs')->where('bid', $bid)->update(['cp_source' => $cp]);
+            }
+        } else {
+            $cp = '';
+            if ($book_info->ly_bid) {
+                $cp = $this->getcp($book_info->ly_bid);
+            }
+            $product_id = $this->addproducts();
+            $vip_seq = 0;
+            $vip = DB::table('chapters')->where('bid', $bid)->where('is_vip', 1)->select('sequence')->orderBy('sequence')->first();
+            if ($vip && isset($vip->sequence)) {
+                $vip_seq = $vip->sequence;
+            }
+            $this->update_info[$bid] = [];
+            $this->update_info[$bid]['add'] = true;
+            $this->update_info[$bid]['channel_name'] = $book_info->category_id >=13 ? '女频':'男频';
+            $this->update_info[$bid]['update_type'] = 'add_book';
+            $this->update_info[$bid]['book_name'] = $book_info->name;
+            DB::table('book_configs')->insert([
+                'bid' => $bid,
+                'force_subscribe_chapter_seq' => 10,
+                'book_name' => $book_info->name,
+                'price' => '8.99',
+                'cover' => $book_info->cover,
+                'charge_type' => 'CHAPTER',
+                'is_on_shelf' => 0,
+                'product_id' => $product_id,
+                'cp_source' => $cp,
+                'vip_seq' => $vip_seq,
+                'created_at' => date('Y-m-d H:i:s'),
+                'updated_at' => date('Y-m-d H:i:s')
+            ]);
+        }
+    }
+
+
+    public function bookChapterInfo($bid)
+    {
+        $res1 = DB::table('chapters')->where('bid', $bid)->orderBy('sequence', 'asc')->select('id')->first();
+        $res2 = DB::table('chapters')->where('bid', $bid)->orderBy('sequence', 'desc')->select('id', 'name')->first();
+        $res3 = DB::table('chapters')->where('bid', $bid)->count();
+
+        $res4 = DB::table('chapters')->where('bid', $bid)->sum('size');
+        if(isset($this->update_info[$bid])){
+            $this->update_info[$bid]['update_words'] = $res4;
+            $this->update_info[$bid]['update_chapter_count'] = $res3;
+        }
+        DB::table('books')->where('id', $bid)->update(
+            [
+                'chapter_count' => $res3,
+                'first_cid' => $res1->id,
+                'last_cid' => $res2->id,
+                'size' => $res4,
+                'last_chapter' => $res2->name
+            ]
+        );
+    }
+
+    public function getcp($ly_bid)
+    {
+        return '';
+    }
+
+
+    /**
+     * 调整单本书的顺序
+     * @param $bid
+     */
+    public function adjustSequentOne($bid)
+    {
+        $chapter_list = DB::table('chapters')->orderBy('sequence')->where('bid', $bid)->select('id')->get();
+        $prev = 0;
+
+        foreach ($chapter_list as $chapter) {
+            if ($prev) {
+                DB::table('chapters')->where('id', $chapter->id)->update(['prev_cid' => $prev]);
+                DB::table('chapters')->where('id', $prev)->update(['next_cid' => $chapter->id]);
+            }
+            $prev = $chapter->id;
+        }
+    }
+
+    private function recordUpdateInfo()
+    {
+        if(!$this->update_info) {
+            return;
+        }
+        foreach ($this->update_info as $k=>$v){
+            if(!$v['add']) continue;
+            // 2 book_updates 的更新记录
+            DB::table('book_updates')->insert([
+                'bid' => $k,
+                'book_name' => $v['book_name'],
+                'channel_name' => $v['channel_name'],
+                'update_date' => date('Y-m-d'),
+                'update_chapter_count' => $v['update_chapter_count'],
+                'update_words' => $v['update_words'],
+                'update_type' => $v['update_type'],
+                'created_at' => date('Y-m-d H:i:s'),
+                'updated_at' => date('Y-m-d H:i:s')
+            ]);
+        }
+    }
+}

+ 168 - 0
app/Console/Commands/BookAttr.php

@@ -0,0 +1,168 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Book\Models\Chapter;
+use Illuminate\Console\Command;
+use DB;
+use Redis;
+
+class BookAttr extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:attr {--start=} {--end=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //$this->tempReadRecord();
+        //print_r($res);
+        $start = $this->option('start');
+        $end = $this->option('end');
+        if($start && $end){
+            while (strtotime($start)<=strtotime($end)){
+                //echo $start.PHP_EOL;
+                $this->sendOrderDayAttr($start);
+                $start = date('Y-m-d',strtotime($start)+86400);
+            }
+        }else{
+            $this->sendOrderDayAttr(date('Y-m-d',time()-86400));
+            $this->sendOrderSevenDayAttr();
+        }
+    }
+
+    private function sendOrderDayAttr($day){
+        $res = DB::table('send_orders')
+            ->where('created_at','>=',$day)
+            ->where('created_at','<=',$day.' 23:59:59')
+            ->select('book_id','distribution_channel_id',DB::raw('count(*) as counts'))
+            ->groupBy('book_id')
+            ->groupBy('distribution_channel_id')
+            ->get();
+        $data = [];
+        foreach ($res as $v){
+            if($v->book_id){
+                $book_total_send_order_stats = DB::table('book_total_send_order_stats')->where('bid',$v->book_id)->first();
+                if($book_total_send_order_stats){
+                    DB::table('book_total_send_order_stats')->where('bid',$v->book_id)->increment('num',$v->counts,['updated_at'=>date('Y-m-d H:i:s')]);
+                }else{
+                    DB::table('book_total_send_order_stats')->insert([
+                        'bid'=>$v->book_id,
+                        'num'=>$v->counts,
+                        'created_at'=>date('Y-m-d H:i:s'),
+                        'updated_at'=>date('Y-m-d H:i:s')
+                        ]);
+                }
+                $channel_book_total_send_order_stats =DB::table('channel_book_total_send_order_stats')
+                ->where('bid',$v->book_id)
+                ->where('distribution_channel_id',$v->distribution_channel_id)
+                ->first();
+                if($channel_book_total_send_order_stats){
+                    DB::table('channel_book_total_send_order_stats')
+                    ->where('bid',$v->book_id)
+                    ->where('distribution_channel_id',$v->distribution_channel_id)
+                    ->increment('num',$v->counts,['updated_at'=>date('Y-m-d H:i:s')]);
+                }else{
+                    DB::table('channel_book_total_send_order_stats')->insert([
+                        'bid'=>$v->book_id,
+                        'num'=>$v->counts,
+                        'distribution_channel_id'=>$v->distribution_channel_id,
+                        'created_at'=>date('Y-m-d H:i:s'),
+                        'updated_at'=>date('Y-m-d H:i:s')
+                        ]);
+                }
+                
+                $data[] = [
+                    'bid'=>$v->book_id,
+                    'num'=>$v->counts,
+                    'distribution_channel_id'=>$v->distribution_channel_id,
+                    'day'=>$day,
+                    'created_at'=>date('Y-m-d H:i:s'),
+                    'updated_at'=>date('Y-m-d H:i:s')
+                ] ;
+            }
+        }
+        DB::table('book_send_order_stats')->insert($data);
+    }
+
+    private function sendOrderSevenDayAttr(){
+        $result = DB::table('book_total_send_order_stats')->select('id','bid')->get();
+        foreach ($result as  $value) {
+            $num = DB::table('book_send_order_stats')->where('bid',$value->bid)->where('day','>=',date('Y-m-d', strtotime('-7 day')))->sum('num');
+            DB::table('book_total_send_order_stats')->where('id',$value->id)->update(['seven_day_num'=>$num]); 
+        }
+    }
+
+    private function tempReadRecord(){
+        $data = [];
+        $book_chapter_seq = [];
+        $j = 1;
+        for ($i = 10000;$i<=24139688;$i++){
+            $read_bids = Redis::hgetall('book_read:' . $i);
+            if(!$read_bids)
+                continue;
+
+            foreach ($read_bids as $key=>$v){
+                if($key == 'last_read' || $key == 'send_order_id'){
+                    continue;
+                }
+                if(!isset($book_chapter_seq[$key])){
+                    $book_chapter_seq[$key] = $this->chapters($key);
+                }
+                $record = explode('_', $v);
+                $cid = 0;
+                if(isset($record[0])){
+                    $cid = $record[0];
+                }
+                $seq = 0;
+                if(isset($book_chapter_seq[$key][$cid])){
+                    $seq = $book_chapter_seq[$key][$cid];
+                }
+                $data[]  = [
+                    'bid'=>$key,
+                    'uid'=>$i,
+                    'cid'=>$cid,
+                    'seq'=>$seq,
+                    'created_at'=>date('Y-m-d H:i:s'),
+                    'updated_at'=>date('Y-m-d H:i:s')
+                ];
+                $j++;
+                if($j%1000 == 0){
+                    DB::table('read_record_temp')->insert($data);
+                    $data = [];
+                }
+            }
+        }
+        DB::table('read_record_temp')->insert($data);
+    }
+
+    private function chapters($bid){
+        return Chapter::where('bid',$bid)->select('id','sequence')->get()->pluck('sequence','id')->all();
+    }
+
+}

+ 72 - 0
app/Console/Commands/BookGiftStats/BookGiftStatsByBook.php

@@ -0,0 +1,72 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: songdb
+ * Date: 2017/12/26
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\BookGiftStats;
+
+use App\Modules\BookGifts\Services\BookGiftsStatsByBookService;
+use Log;
+use DB;
+use Illuminate\Console\Command;
+
+class BookGiftStatsByBook extends Command
+{
+    /**
+     * 执行命令   php artisan generate_order_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'BookGiftDailyStatsByBook';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '送礼记录数据按书统计';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======送礼记录数据按书统计 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        Log::info("======送礼记录数据按书统计 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $start = date('Y-m-d 00:00:00',strtotime('-1 day'));
+        $end   = date('Y-m-d 23:59:59',strtotime('-1 day'));
+        $res = DB::select("SELECT bid,name,count(book_gifts_send.id) as send_times,COUNT(DISTINCT book_gifts_send.uid) as send_user_num,sum(book_gifts_send.cost) as cost_sum
+ FROM book_gifts_send
+ LEFT JOIN books ON books.id=book_gifts_send.bid
+ WHERE book_gifts_send.created_at BETWEEN '{$start}' AND '{$end}'
+ GROUP BY bid ");
+        foreach ($res as $item){
+            try{
+                $data_to_add = array(
+                    'date'=>date('Y-m-d'),
+                    'bid'=>$item->bid,
+                    'book_name'=>$item->name,
+                    'gift_send_times'=>$item->send_times,
+                    'gift_send_user_num'=>$item->send_user_num,
+                    'gift_send_cost'=>$item->cost_sum,
+                );
+
+                BookGiftsStatsByBookService::addBookStats($data_to_add);
+            }catch (\Exception $e){
+                \Log::error('add Book Gifts Stats Failed:'.$e->getMessage());
+            }
+        }
+
+        Log::info("======送礼记录数据按书统计 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======送礼记录数据按书统计 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+}

+ 74 - 0
app/Console/Commands/BookGiftStats/BookGiftStatsByGift.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: songdb
+ * Date: 2017/12/26
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\BookGiftStats;
+
+use DB;
+use App\Modules\BookGifts\Services\BookGiftsStatsByGiftService;
+use Log;
+use Illuminate\Console\Command;
+
+class BookGiftStatsByGift extends Command
+{
+    /**
+     * 执行命令   php artisan generate_order_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'BookGiftDailyStatsByGift';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '送礼记录数据按礼物统计';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======送礼记录数据按礼物统计 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        Log::info("======送礼记录数据按礼物统计 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $start = date('Y-m-d 00:00:00',strtotime('-1 day'));
+        $end   = date('Y-m-d 23:59:59',strtotime('-1 day'));
+        \Log::info('start:'.$start);
+        \Log::info('end:'.$end);
+        $res = DB::select("SELECT gift_id,book_gifts.name_desc,count(book_gifts_send.id) as send_times,COUNT(DISTINCT book_gifts_send.uid) as send_user_num,sum(book_gifts_send.cost) as cost_sum
+ FROM book_gifts_send
+ LEFT JOIN book_gifts ON book_gifts.id=book_gifts_send.gift_id
+ WHERE book_gifts_send.created_at BETWEEN '{$start}' AND '{$end}'
+ GROUP BY gift_id");
+        foreach ($res as $item){
+            try{
+                $data_to_add = array(
+                    'date'=>date('Y-m-d'),
+                    'gift_id'=>$item->gift_id,
+                    'gift_name'=>$item->name_desc,
+                    'gift_send_times'=>$item->send_times,
+                    'gift_send_user_num'=>$item->send_user_num,
+                    'gift_send_cost'=>$item->cost_sum,
+                );
+
+                BookGiftsStatsByGiftService::addGiftStats($data_to_add);
+            }catch (\Exception $e){
+                \Log::error('add Book Gifts Stats Failed2:'.$e->getMessage());
+            }
+        }
+
+        Log::info("======送礼记录数据礼物统计 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======送礼记录数据按礼物统计 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+}

+ 91 - 0
app/Console/Commands/BookSearchInfoStat.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Book\Models\BookSearchStat;
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Storage;
+
+class BookSearchInfoStat extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book_search_stat';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '用户搜索图书记录信息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $end_time = date("Y-m-d", strtotime("-1 day"));
+        $begin_time = date("Y-m-d", strtotime("-8 day"));
+        $type = 'WECHAT';
+        $wechat_search_result = BookSearchStat::getInfo(compact('begin_time', 'end_time', 'type'), true);
+
+        $type = 'WAP';
+        $wap_search_result = BookSearchStat::getInfo(compact('begin_time', 'end_time', 'type'), true);
+
+        $this->sendResultEmail($wechat_search_result, $wap_search_result, $begin_time, $end_time);
+    }
+
+    public function sendResultEmail($wechat_search_result, $wap_search_result, $start_date, $end_date)
+    {
+        if ($wechat_search_result && count($wechat_search_result) > 0) {
+            $filename = '微信内搜索.' . 'csv';
+            Storage::append($filename, mb_convert_encoding("关键词,搜索人数,搜索次数", 'gbk'));
+            $str = '';
+            foreach ($wechat_search_result as $item) {
+                $str .= "$item->content,$item->user_num,$item->search_num\r\n";
+            }
+            Storage::append($filename, mb_convert_encoding($str, 'gbk'));
+        }
+
+        if ($wap_search_result && count($wap_search_result) > 0) {
+            $filename = 'wap内搜索.' . 'csv';
+            Storage::append($filename, mb_convert_encoding("关键词,搜索人数,搜索次数", 'gbk'));
+            $str = '';
+            foreach ($wap_search_result as $item) {
+                $str .= "$item->content,$item->user_num,$item->search_num\r\n";
+            }
+            Storage::append($filename, mb_convert_encoding($str, 'gbk'));
+        }
+
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰']
+        );
+
+        $file_path1 = storage_path('app/微信内搜索.csv');
+        $file_path2 = storage_path('app/wap内搜索.csv');
+        $attach = [$file_path1, $file_path2];
+        $body = '搜索关键字统计,详情请见附件';
+        SendStatsEmailService::SendMultyHtmlEmailWithAcce($to_user, ['subject' => $start_date . '至' . $end_date . " 搜索关键字统计", 'body' => $body], $attach);
+
+        unlink($file_path1);
+        unlink($file_path2);
+    }
+}

+ 210 - 0
app/Console/Commands/BookUpdate.php

@@ -0,0 +1,210 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use GuzzleHttp\Client;
+use App\Modules\Book\Models\Book;
+use App\Modules\Book\Models\Chapter;
+use Log;
+use App\Modules\Book\Services\BookConfigService;
+use App\Modules\Book\Services\ChapterService;
+
+class BookUpdate extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:update';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新所有图书章节内容';
+
+    private $client;
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+        $this->client = new Client(['timeout' => 10.0, 'allow_redirects' => true]);
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->updateAll();
+    }
+
+    /**
+     * 更新所有书的章节
+     */
+    public function updateAll()
+    {
+        set_time_limit(0);
+        $exist_book = Book::where('ly_bid', '!=', '0')->where('status', 0)->select('id', 'ly_bid')->get();
+        foreach ($exist_book as $v) {
+            //Log::info('updateAll bid is: '.$v->id.'$ly_bid is :'.$v->ly_bid.'----------------------------');
+            $this->updateOne($v->id, $v->ly_bid);
+        }
+    }
+
+    /**
+     * 更新章节内容 一本书的
+     * @param $bid
+     * @return int|string
+     */
+    public function updateOne($bid, $ly_bid)
+    {
+        set_time_limit(0);
+        //$max_sequence = Chapter::where('bid', $bid)->max('sequence');
+        //$max_sequence = $max_sequence ? $max_sequence : -1;
+        //$max_sequence_chapter = Chapter::where('bid', $bid)->where('sequence', $max_sequence)->select('id')->first();
+        //$max_sequence_chapter_id = isset($max_sequence_chapter->id) ? $max_sequence_chapter->id : 0;
+        $this->bookStatus($bid, $ly_bid);
+
+        $last_chapter = Chapter::where('bid', $bid)
+            ->select('id', 'name', 'sequence', 'prev_cid', 'next_cid')
+            ->orderBy('sequence', 'desc')
+            ->first();
+        $last_chapter_from_third = Chapter::where('bid', $bid)
+            ->where('ly_chapter_id', '>', 0)
+            ->select('id', 'name', 'sequence', 'prev_cid', 'next_cid', 'ly_chapter_id')
+            ->orderBy('sequence', 'desc')
+            ->first();
+        $max_sequence_chapter_id = isset($last_chapter->id) ? $last_chapter->id : 0;
+        $max_sequence = isset($last_chapter->sequence) ? $last_chapter->sequence : 0;
+        $from_sequence = $max_sequence;
+
+        try {
+            $chapter_list_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapterlist&bid=%s&token=sefaf23h7face";
+            $res = $this->client->get(sprintf($chapter_list_fromat, $ly_bid));
+            $res = $res->getBody()->getContents();
+        } catch (\Exception $e) {
+            Log::info($e);
+            return '';
+        }
+        if (!$res) return '';
+        $res = json_decode($res, true);
+        if ($res && isset($res['code']) && $res['code'] == 200) {
+
+        } else {
+            return '';
+        }
+        $j = 0;
+
+        if (isset($res['data']) && $res['data'] && is_array($res['data'])) {
+        } else {
+            return '';
+        }
+
+        $local_count = Chapter::where('bid', $bid)->where('ly_chapter_id', '>', 0)->count();
+        $remote_count = 0;
+
+        foreach ($res['data'] as $item1) {
+            $remote_count += count($item1['chapters']);
+            $item1 = null;
+        }
+        Log::info('$remote_count is: ' . $remote_count . '====$local_count :' . $local_count . '----');
+        if ($remote_count == $local_count) return '';
+        Log::info('$bid =: ' . $bid . '---is lack---');
+        $start = false;
+        if (!$last_chapter) {
+            $start = true;
+        }
+        $ly_last_chapter_id = 0;
+        if ($last_chapter_from_third && isset($last_chapter_from_third->ly_chapter_id)) {
+            $ly_last_chapter_id = $last_chapter_from_third->ly_chapter_id;
+        }
+
+        foreach ($res['data'] as $v1) {
+            foreach ($v1['chapters'] as $v) {
+
+                /*if ($v['chapter_order_number'] <= $max_sequence-1) {
+                    continue;
+                }
+
+                if (Chapter::where('bid', $bid)->where('ly_chapter_id', $v['chapter_id'])->count()) {
+                    continue;
+                }*/
+                if (!$start) {
+                    if ($v['chapter_id'] != $ly_last_chapter_id) {
+                        continue;
+                    } else {
+                        \Log::info($v1);
+                        $start = true;
+                        continue;
+                    }
+                }
+
+                Log::info('bid: ' . $bid . '----ly_chapter_id: ' . $v['chapter_id']);
+                $chapter_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapter&bid=%s&cid=%s&token=sefaf23h7face";
+                $cahpter_content_res = $this->client->get(sprintf($chapter_fromat, $ly_bid, $v['chapter_id']));
+                $cahpter_content = $cahpter_content_res->getBody()->getContents();
+
+                $temp = [
+                    'bid' => $bid,
+                    'name' => $v['chapter_name'],
+                    'sequence' => ++$max_sequence,
+                    'is_vip' => $v['chapter_need_pay'],
+                    'prev_cid' => $max_sequence_chapter_id,
+                    'next_cid' => '',
+                    'recent_update_at' => date('Y-m-d H:i:s', $v['chapter_last_update_time']),
+                    'ly_chapter_id' => $v['chapter_id']
+                ];
+                if ($cahpter_content) {
+                    $cahpter_content = json_decode($cahpter_content, true);
+                    $temp['size'] = ceil(strlen($cahpter_content['data']['chapter_content']) / 3);
+                    $temp['content'] = $cahpter_content['data']['chapter_content'];
+                }
+                $insert_res = Chapter::create($temp);
+                Chapter::where('id', $max_sequence_chapter_id)->update(['next_cid' => $insert_res->id]);
+                $max_sequence_chapter_id = $insert_res->id;
+                $temp = null;
+                $j++;
+            }
+        }
+
+        $chapter_count = Chapter::where('bid', $bid)->count();
+        $chapter_size = Chapter::where('bid', $bid)->sum('size');
+        if ($j > 0) {
+            Book::where('id', $bid)->update(['chapter_count' => $chapter_count, 'last_cid' => $max_sequence_chapter_id, 'size' => $chapter_size, 'last_chapter' => $v['chapter_name']]);
+            //ChapterService::splitContentAll($bid,$from_sequence);
+        }
+        return $j;
+    }
+
+
+    private function bookStatus($bid, $ly_bid)
+    {
+        $status = 0;
+        try {
+            $book_info_url_format = "http://www.leyuee.com/services/zwfx.aspx?method=bookinfo&token=sefaf23h7face&bid=%s";
+            $res = $this->client->get(sprintf($book_info_url_format, $ly_bid));
+            $res = $res->getBody()->getContents();
+            if ($res) {
+                $res = json_decode($res, true);
+                if (isset($res['data']) && isset($res['data']['book_state'])) {
+                    $status = $res['data']['book_state'];
+                }
+            }
+        } catch (\Exception $e) {
+
+        }
+        if ($status) {
+            Book::where('id', $bid)->update(['status' => $status]);
+        }
+    }
+}

+ 257 - 0
app/Console/Commands/BookUpdateOne.php

@@ -0,0 +1,257 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use GuzzleHttp\Client;
+use App\Modules\Book\Models\Book;
+use App\Modules\Book\Models\Chapter;
+use App\Modules\Book\Services\ChapterService;
+use App\Modules\Book\Services\BookConfigService;
+use DB;
+use Log;
+
+class BookUpdateOne extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:updateone
+                            {--bid= : the id of a book}
+                            {--content}
+                            {--start=}
+                            {--end=}
+                            {--withname}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新图书章节内容';
+
+    private $client;
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+        $this->client = new Client(['timeout'  => 8.0,'allow_redirects'=>true]);
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $bid = $this->option('bid');
+        if(empty($bid)) return 0;
+        $content = $this->option('content');
+        if($content){
+            $start = $this->option('start');
+            $end = $this->option('end');
+            $withname = $this->option('withname');
+            return $this->updateExistContent($bid,$start,$end,$withname);
+        }
+
+        return $this->updateOne($bid);
+    }
+
+
+    /**
+     * 更新章节内容 一本书的
+     * @param $bid
+     * @return int|string
+     */
+    public function updateOne($bid){
+        set_time_limit(0);
+        $book_info = Book::find($bid);
+        if(empty($book_info) || empty($book_info->ly_bid)) return -1;
+        $this->bookStatus($bid,$book_info->ly_bid);
+        //$max_sequence = Chapter::where('bid',$bid)->max('sequence');
+        //$max_sequence = $max_sequence?$max_sequence:-1;
+        //$max_sequence_chapter = Chapter::where('bid',$bid)->where('sequence',$max_sequence)->select('id')->first();
+        //$max_sequence_chapter_id = isset($max_sequence_chapter->id)?$max_sequence_chapter->id:0;
+
+        $last_chapter = Chapter::where('bid',$bid)
+            ->select('id','name','sequence','prev_cid','next_cid')
+            ->orderBy('sequence','desc')
+            ->first();
+        $last_chapter_from_third = Chapter::where('bid',$bid)
+            ->where('ly_chapter_id','>',0)
+            ->select('id','name','sequence','prev_cid','next_cid','ly_chapter_id')
+            ->orderBy('sequence','desc')
+            ->first();
+        $max_sequence_chapter_id = isset($last_chapter->id)?$last_chapter->id:0;
+        $max_sequence = isset($last_chapter->sequence)?$last_chapter->sequence:0;
+
+        $chapter_list_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapterlist&bid=%s&token=sefaf23h7face";
+        $res = $this->client->get(sprintf($chapter_list_fromat,$book_info->ly_bid));
+        $res = $res->getBody()->getContents();
+        if(!$res) return '';
+        $book_config_info = DB::table('book_configs')->where('bid',$bid)->first();
+        $res = json_decode($res,true);
+        $j = 0;
+        $size = 0;
+        $local_count = Chapter::where('bid',$bid)->where('ly_chapter_id','>',0)->count();
+        $remote_count = 0;
+
+        foreach ($res['data'] as $item1) {
+            $remote_count += count($item1['chapters']);
+            $item1 = null;
+        }
+        if($remote_count == $local_count) return '';
+        $start = false;
+        if(!$last_chapter){
+            $start = true;
+        }
+        $ly_last_chapter_id = 0;
+        if($last_chapter_from_third && isset($last_chapter_from_third->ly_chapter_id)){
+            $ly_last_chapter_id = $last_chapter_from_third->ly_chapter_id;
+        }
+
+        foreach ($res['data'] as $v1) {
+            foreach ($v1['chapters'] as $v) {
+                /*if ($v['chapter_order_number'] <= $max_sequence-1) {
+                    continue;
+                }*/
+                if(!$start){
+                    if($v['chapter_id'] != $ly_last_chapter_id){
+                        continue;
+                    }else{
+                        \Log::info($v1);
+                        $start = true;
+                        continue;
+                    }
+                }
+                /*if (Chapter::where('bid', $bid)->where('ly_chapter_id', $v['chapter_id'])->count()) {
+                    continue;
+                }*/
+
+                $chapter_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapter&bid=%s&cid=%s&token=sefaf23h7face";
+                $cahpter_content_res = $this->client->get(sprintf($chapter_fromat, $book_info->ly_bid, $v['chapter_id']));
+                $cahpter_content = $cahpter_content_res->getBody()->getContents();
+
+                $temp = [
+                    'bid' => $bid,
+                    'name' => $v['chapter_name'],
+                    'sequence' => ++$max_sequence,
+                    'is_vip' => $v['chapter_need_pay'],
+                    'prev_cid' => $max_sequence_chapter_id,
+                    'next_cid' => '',
+                    'recent_update_at' => date('Y-m-d H:i:s', $v['chapter_last_update_time']),
+                    'ly_chapter_id' => $v['chapter_id']
+                ];
+                if ($cahpter_content) {
+                    $cahpter_content = json_decode($cahpter_content, true);
+                    $temp['size'] = ceil(strlen($cahpter_content['data']['chapter_content']) / 3);
+                    $temp['content'] = $cahpter_content['data']['chapter_content'];
+                    $size += $temp['size'];
+                }
+                $insert_res = Chapter::create($temp);
+                Chapter::where('id', $max_sequence_chapter_id)->update(['next_cid' => $insert_res->id]);
+                $max_sequence_chapter_id = $insert_res->id;
+                $temp = null;
+                $j++;
+            }
+        }
+        $chapter_count = Chapter::where('bid',$bid)->count();
+        $chapter_size = Chapter::where('bid',$bid)->sum('size');
+        if($j>0){
+            Book::where('id',$bid)->update(['chapter_count'=>$chapter_count,'last_cid'=>$max_sequence_chapter_id,'size'=>$chapter_size,'last_chapter'=>$v['chapter_name']]);
+            $this->recordUpdateInfo($bid,[
+                'book_name'=>$book_config_info->book_name,
+                'update_chapter_count'=>$j,
+                'update_words'=>$size,
+                'update_type'=>'add_chapter',
+                'channel_name'=>$book_info->category_id >=13 ? '女频':'男频'
+            ]);
+        }
+        return $j;
+    }
+
+    private function bookStatus($bid,$ly_bid){
+        $status = 0;
+        try{
+            $book_info_url_format =   "http://www.leyuee.com/services/zwfx.aspx?method=bookinfo&token=sefaf23h7face&bid=%s";
+            $res = $this->client->get(sprintf($book_info_url_format,$ly_bid));
+            $res = $res->getBody()->getContents();
+            if($res){
+                $res = json_decode($res,true);
+                if(isset($res['data']) && isset($res['data']['book_state'])){
+                    $status = $res['data']['book_state'];
+                }
+            }
+        }catch (\Exception $e){
+
+        }
+        if($status){
+            Book::where('id',$bid)->update(['status'=>$status]);
+        }
+    }
+
+    private function updateExistContent($bid,$start=0,$end=0,$name=false){
+        $book_info = Book::find($bid);
+        if(empty($book_info) || empty($book_info->ly_bid)) return -1;
+
+
+        $chapter_list_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapterlist&bid=%s&token=sefaf23h7face";
+        $res = $this->client->get(sprintf($chapter_list_fromat,$book_info->ly_bid));
+        $res = $res->getBody()->getContents();
+        if(!$res) return '';
+        $res = json_decode($res,true);
+        if(!isset($res['data']))
+            return '';
+        foreach ($res['data'] as $v1){
+            foreach ($v1['chapters'] as $v){
+                if($start && ($v['chapter_order_number']+1<$start) ){
+                    continue;
+                }
+                if($end && ($v['chapter_order_number']+1>$end)){
+                    break;
+                }
+                $chapter_fromat = "http://www.leyuee.com/services/zwfx.aspx?method=chapter&bid=%s&cid=%s&token=sefaf23h7face";
+                $cahpter_content_res = $this->client->get(sprintf($chapter_fromat, $book_info->ly_bid, $v['chapter_id']));
+                $cahpter_content = $cahpter_content_res->getBody()->getContents();
+                $cahpter_content = json_decode($cahpter_content, true);
+                if($cahpter_content && isset( $cahpter_content['data']['chapter_content']) && !empty( $cahpter_content['data']['chapter_content'])){
+                    //$temp['size'] = ceil(strlen($cahpter_content['data']['chapter_content']) / 3);
+                    //$temp['content'] = $cahpter_content['data']['chapter_content'];
+                    $chapter = Chapter::where('bid', $bid)->where('sequence', $v['chapter_order_number']+1)->first();
+                    if($chapter){
+                        $chapter->content = $cahpter_content['data']['chapter_content'];
+                        if($name){
+                            $chapter->name =$v['chapter_name'];
+                        }
+                        $chapter->size = ceil(strlen($cahpter_content['data']['chapter_content']) / 3);
+                        ChapterService::editChapter($chapter);
+                    }
+                }
+            }
+        }
+    }
+
+    private function recordUpdateInfo($bid, $data)
+    {
+        // 2 book_updates 的更新记录
+        DB::table('book_updates')->insert([
+            'bid' => $bid,
+            'book_name' => $data['book_name'],
+            'channel_name' => $data['channel_name'],
+            'update_date' => date('Y-m-d'),
+            'update_chapter_count' => $data['update_chapter_count'],
+            'update_words' => $data['update_words'],
+            'update_type' => $data['update_type'],
+            'created_at' => date('Y-m-d H:i:s'),
+            'updated_at' => date('Y-m-d H:i:s')
+        ]);
+    }
+}

+ 136 - 0
app/Console/Commands/BusinessChannelStatTask.php

@@ -0,0 +1,136 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/12/26
+ * Time: 下午3:29
+ */
+
+namespace App\Console\Commands;
+use App\Modules\Trade\Models\OrderDayStat;
+use App\Modules\Trade\Models\OrderStat;
+use App\Modules\Channel\Services\BusinessChannelDayStatService;
+use App\Modules\Channel\Services\BusinessChannelStatService;
+use App\Modules\Channel\Services\ChannelOrdersService;
+use App\Modules\Channel\Services\ChannelService;
+use App\Modules\OfficialAccount\Services\ForceSubscribeService;
+use App\Modules\SendOrder\Services\SendOrderService;
+use App\Modules\Statistic\Services\WapVisitStatService;
+use App\Modules\User\Services\UserService;
+use Log;
+use Illuminate\Console\Command;
+
+class BusinessChannelStatTask extends Command
+{
+
+    /**
+     * 执行命令   php artisan BusinessChannelStat_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'BusinessChannelStat_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日商务渠道数据生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日生商务渠道数据生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======每日商务渠道数据生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+
+        $dateNow = date("Y-m-d");
+//        $dateNow = "2018-01-30";
+
+        $yesterStartDay = date('Y-m-d', strtotime($dateNow." -1 day"))." 00:00:00";
+        $yesterEndDay = date('Y-m-d', strtotime($dateNow))." 00:00:00";
+
+        $last_monthStartDay = date('Y-m', strtotime($dateNow." -1 month"))."-01 00:00:00";
+        $current_monthStartDay = date('Y-m', strtotime($dateNow))."-01  00:00:00";
+
+        $beginLastweek=date('Y-m-d H:i:s',mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y')));
+        $endLastweek=date('Y-m-d H:i:s',mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y')));
+
+        $current_week_start = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y")));
+        $current_week_end = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")));
+
+        $channels = ChannelService::getAllChannels();
+        foreach ($channels as $channel) {
+            $channel_data = OrderStat::getByChannelId($channel['id']);
+            $channel_day_data = OrderDayStat::getYesterdaySumByChannelId($channel['id']);
+            $business_stat = BusinessChannelStatService::getByChannelID($channel->id);
+
+            if(!$channel_data || !$channel_day_data){
+                Log::info($channel['id']."日数据未生成".date("y-m-d H:i:s"."\n"));
+                continue;
+            }
+            $userRegisterNum = $channel_day_data->register_user_num;//昨日注册
+            $sendOrderDataNum = $channel_day_data->send_order_num;//昨日派单创建数
+
+            try{
+                $paramsA = [
+                    'distribution_channel_id' => $channel['id'],
+                    'date' => $yesterStartDay,
+                    'register_user_num' => $userRegisterNum,
+                    'send_order_num' => $sendOrderDataNum,
+                    'is_login_yesterday'=>UserService::judgeUserYesterdayLogin($channel['id'],$yesterStartDay,$yesterEndDay)
+                ];
+                BusinessChannelDayStatService::createBusinessChannelDayStat($paramsA);
+            }catch (\Exception $exception){
+                \Log::error($exception->getMessage());
+            }
+
+            $yesterday_register_user_num = $userRegisterNum;
+            $total_register_user_num = $channel_data->register_user_num;
+            $total_send_order_num = $channel_data->send_order_num;
+            //当月新增站点充值
+            $current_month_new_channel_recharge = strtotime($channel->created_at) >= strtotime(date('Y-m-01')) ? $channel_data->current_month_recharge_amount : 0;
+            $current_month_channel_recharge = $channel_data->current_month_recharge_amount;//当月总充值
+            $channel_total_recharge=$channel_data->total_recharge_amount;//历史总充值
+
+            $paramsB = [
+                'yesterday_register_user_num' => $yesterday_register_user_num,
+                'total_register_user_num' => $total_register_user_num,
+                'total_send_order_num' => $total_send_order_num,
+                'current_month_new_channels_recharge'=>$current_month_new_channel_recharge,
+                'current_month_channels_recharge'=>$current_month_channel_recharge,
+                'service_account_num' =>BusinessChannelStatService::getServiceAccountNum($channel['id']),
+                'last_week_login_days' =>0,//BusinessChannelStatService::getLoginDays($channel['id'],$beginLastweek,$endLastweek),
+                'current_week_login_days'=>0,//BusinessChannelStatService::getLoginDays($channel['id'],$current_week_start,$current_week_end),
+                'yesterday_create_orders'=>$sendOrderDataNum,
+                'is_login_yesterday'=>$paramsA['is_login_yesterday'],
+                'channel_total_recharge'=>$channel_total_recharge,
+
+            ];
+            if(date('d')=='01'){//月初第一天
+                $paramsB['last_month_channels_recharge'] = $channel_data->last_month_recharge_amount;
+                $paramsB['last_month_new_channel_recharge'] =$business_stat ? $business_stat->current_month_new_channels_recharge : 0;
+                $paramsB['last_month_register_user_num'] = $business_stat ? $business_stat->current_month_register_user_num : 0;
+                $paramsB['current_month_register_user_num'] = $userRegisterNum;
+            }else{
+                $paramsB['current_month_register_user_num'] = $business_stat ? $business_stat->current_month_register_user_num + $userRegisterNum : $userRegisterNum;
+            }
+
+            if(date('w')=='1'){//周一
+                $paramsB['last_week_actual_send_orders'] = $business_stat ? $business_stat->current_week_actual_send_orders : 0;
+            }else{
+                $paramsB['current_week_actual_send_orders'] = SendOrderService::getPeriodActualSendOrdersNum($channel['id'], $current_week_start,$current_week_end);
+            }
+            BusinessChannelStatService::crateUpdate($channel['id'], $paramsB);
+        }
+
+        Log::info("======每日商务渠道数据生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======每日商务渠道数据生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+}

+ 56 - 0
app/Console/Commands/CP/GenerateCpBookBetweenStat.php

@@ -0,0 +1,56 @@
+<?php
+/**
+ * zhoulj
+ * 2018-05-15
+ */
+
+namespace App\Console\Commands\CP;
+
+use App\Modules\CP\Services\GenerateCpBookStatService;
+use Illuminate\Console\Command;
+use Log;
+
+class GenerateCpBookBetweenStat extends Command
+{
+    /**
+     * 执行命令   php artisan cp_generate_cp_book_between_stat 2018-10-01 2018-11-01
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'cp_generate_cp_book_between_stat {start_date} {end_date}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'CP图书订阅指定时间区间数据生成';
+
+    /**
+     * Execute the console command.
+     * 注意:start_date <= 计算区间 <= end_date
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======CP图书订阅指定时间区间数据生成 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======CP图书订阅指定时间区间数据生成【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        
+        $start_date = $this->argument('start_date');
+        $end_date = $this->argument('end_date');
+        if(empty($start_date) || empty($end_date)){
+        	Log::info('GenerateCpBookBetweenStat param null:start_date:'.$start_date.' end_date:'.$end_date);
+        }
+        $month = date('Y-m',strtotime($start_date));
+        $calculate_date = $end_date;
+        $end_date = date('Y-m-d',strtotime($end_date) - 24*3600);
+        Log::info('start_date:'.$start_date.' end_date:'.$end_date.' month:'.$month.' calculate_date:'.$calculate_date);
+
+        GenerateCpBookStatService::generateCpBookBetweenStat($start_date,$end_date,$month,$calculate_date);
+
+        Log::info("======CP图书订阅指定时间区间数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======CP图书订阅指定时间区间数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+    }
+}

+ 49 - 0
app/Console/Commands/CP/GenerateCpBookStat.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * zhoulj
+ * 2018-05-15
+ */
+
+namespace App\Console\Commands\CP;
+
+use App\Modules\CP\Services\GenerateCpBookStatService;
+use Illuminate\Console\Command;
+use Log;
+
+class GenerateCpBookStat extends Command
+{
+    /**
+     * 执行命令   php artisan cp_generate_cp_book_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'cp_generate_cp_book_stat';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日CP图书订阅数据生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日CP图书订阅数据生成 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======每日CP图书订阅数据生成【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        // 生成每日统计
+        $date = date("Y-m-d", strtotime('-1 day'));
+        GenerateCpBookStatService::generateCpBookDailyStat($date);
+        //GenerateCpBookStatService::generateCpBookDailyStat2('2018-12-09');
+
+        Log::info("======每日CP图书订阅数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======每日CP图书订阅数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+    }
+}

+ 52 - 0
app/Console/Commands/CP/fixCpBookStat.php

@@ -0,0 +1,52 @@
+<?php
+/**
+ * zhoulj
+ * 2018-05-15
+ */
+
+namespace App\Console\Commands\CP;
+
+use App\Modules\CP\Services\GenerateCpBookStatService;
+use Illuminate\Console\Command;
+use Log;
+
+class fixCpBookStat extends Command
+{
+    /**
+     * 执行命令   php artisan cp_generate_cp_book_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'cp_fix_cp_book_stat {--date=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日CP图书订阅数据修复';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日CP图书订阅数据fix 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======每日CP图书订阅数据fix【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        // 生成每日统计
+        if($this->option('date')){
+            $date = $this->option('date');
+        }else{
+            $date = date("Y-m-d", strtotime('-1 day'));
+        }
+        GenerateCpBookStatService::fixCpBookDailyStat($date);
+
+        Log::info("======每日CP图书订阅数据fix【任务执行结束】=====" . $date. "\n");
+        print_r("======每日CP图书订阅数据fix【任务执行结束】=====" .$date. "\n");
+    }
+}

+ 54 - 0
app/Console/Commands/ChangePay.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+
+class ChangePay extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'pay:change {--from=} {--to=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //DB::table('distribution_channels')->whereIn('id',[5,123])->update(['pay_merchant_id'=>8]);
+        $from = $this->option('from');
+        $to = $this->option('to');
+        $this->change($from,$to);
+    }
+
+    private function change($from,$to){
+        DB::table('distribution_channels')->where('pay_merchant_id',$from)->update([
+            'pay_merchant_id'=>$to,
+            'updated_at'=>date('Y-m-d H:i:s')
+        ]);
+    }
+
+}

+ 74 - 0
app/Console/Commands/Channel/CheckStatus.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: songdb
+ * Date: 2017/12/26
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\Channel;
+
+use App\Modules\Channel\Services\ChannelService;
+use App\Modules\SendOrder\Services\SendOrderService;
+use App\Modules\Channel\Services\ChannelUserService;
+
+use Log;
+use Illuminate\Console\Command;
+
+class CheckStatus extends Command
+{
+    /**
+     * 执行命令   php artisan generate_order_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'channel_user_check_status';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '检测渠道账号状态';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======检测渠道账号状态 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        Log::info("======检测渠道账号状态 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $channel_users = ChannelUserService::getChannelList([],1);
+
+        if(count($channel_users))
+        {
+            $channel_users->each(function($channel_user) {
+                $channel_ids = ChannelService::getUserChannelIds($channel_user->id);
+
+                $total_send_order_num = 0;
+                foreach ($channel_ids as $channel_id)
+                {
+                    $distribution_channel_id = $channel_id;
+                    $total_send_order_num += (int)SendOrderService::getPromotionCount(compact('distribution_channel_id'));
+                }
+
+                $except_channel_user_ids = [];
+                //判断是否有派单,并且注册时间大于15天  设置为待审核状态
+                if($total_send_order_num == 0 && time() - strtotime($channel_user->created_at) > 86400*15 && !in_array($channel_user->id,$except_channel_user_ids))
+                {
+                    ChannelUserService::updateChannelData($channel_user->id,['is_enabled'=>0]);
+                }
+
+            });
+        }
+
+        Log::info("======检测渠道账号状态 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======检测渠道账号状态 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+}

+ 70 - 0
app/Console/Commands/Channel/SiteTitle.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Console\Commands\Channel;
+
+use App\Modules\OfficialAccount\Models\OfficialAccount;
+use Illuminate\Console\Command;
+use Redis;
+
+class SiteTitle extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SetSiteTitle';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '设置站点名称';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $channel_ids = $this->getChannelIds();
+        foreach ($channel_ids as $channel_id) {
+            $key = sprintf('channel:setting:%s', $channel_id);
+            $hkey = 'title';
+            $count = $this->getChannelOfficialAccountCount($channel_id);
+            if ($count > 1) {
+                Redis::hDel($key, $hkey);
+            } else if ($count == 1) {
+                $official_account = $this->getOfficialAccount($channel_id);
+                Redis::hSet($key, $hkey, $official_account->nickname);
+            }
+        }
+    }
+
+    private function getChannelIds()
+    {
+        return OfficialAccount::select('distribution_channel_id')->groupBy('distribution_channel_id')->pluck('distribution_channel_id')->all();
+    }
+
+    private function getOfficialAccount(int $channel_id)
+    {
+        return OfficialAccount::where('distribution_channel_id', $channel_id)->first();
+    }
+
+    private function getChannelOfficialAccountCount(int $channel_id)
+    {
+        return  OfficialAccount::where('distribution_channel_id', $channel_id)->count();
+    }
+}

+ 72 - 0
app/Console/Commands/ChannelReaderVisitStats.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Statistic\Services\WapVisitStatService;
+use DB;
+use Illuminate\Console\Command;
+use Redis;
+
+class ChannelReaderVisitStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'channel_reader_visit_stats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function handle()
+    {
+
+        /*$start_date = '2016-08-29';
+        $end_date =  date("Y-m-d", strtotime("-1 day"));
+        $end_timestamp = strtotime($end_date);
+        $start_timestamp = strtotime($start_date);
+
+        // 计算日期段内有多少天
+        $days = ($end_timestamp - $start_timestamp) / 86400 + 1;
+        for ($i = 0; $i < $days; $i++) {
+            $date = date('Y-m-d', $start_timestamp + (86400 * $i));
+            $this->getReadVisitUvInfo($date);
+        }
+
+        /*$yesterday = date("Y-m-d", strtotime("-1 day"));
+        $this->getReadVisitUvInfo($yesterday);*/
+
+        $yesterday = date("Y-m-d", strtotime("-1 day"));
+        $this->getReadVisitUvInfo($yesterday);
+    }
+
+    function getReadVisitUvInfo($date)
+    {
+        $channels = Redis::smembers(sprintf('recordReaderUvAndPv:date:%s', $date));
+        if ($channels) {
+            foreach ($channels as $channel) {
+                $data = WapVisitStatService::getReaderUvAndPv($channel, $date);
+                if ($data) {
+                    $uv = $data['uv'];
+                    $pv = $data['pv'];
+                    $distribution_channel_id = $channel;
+                    $created_at = date("Y-m-d H:i:s");
+                    $updated_at = date("Y-m-d H:i:s");
+                    $data = compact('date', 'uv', 'pv', 'created_at', 'updated_at', 'distribution_channel_id');
+                    DB::table('channel_reader_visit_stats')->insert($data);
+                }
+            }
+        }
+        WapVisitStatService::deleteReaderUvAndPvRedisKey($date);
+    }
+}

+ 66 - 0
app/Console/Commands/ChapterImageTask.php

@@ -0,0 +1,66 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands;
+
+use App\Libs\ChapterToImage;
+use App\Modules\Book\Models\Book;
+use App\Modules\Book\Services\ChapterImageService;
+use Log;
+use Illuminate\Console\Command;
+
+class ChapterImageTask extends Command
+{
+    /**
+     * 执行命令   php artisan chapter_to_image_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'chapter_to_image_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '章节图片生成生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        print_r("======章节图片生成生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======章节图片生成生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+
+        $books = Book::select('id')->orderBy('id')->get();
+        foreach ($books as $book) {
+            $cimages = ChapterImageService::getChapterImage($book['id']);
+            if(empty($cimages) || sizeof($cimages) == 0) {
+
+                ChapterToImage::createChapterImage($book['id']);
+                print_r($book['id']."       ".date("y-m-d H:i:s")."\n");
+                Log::info($book['id']."       ".date("y-m-d H:i:s"."\n"));
+                sleep(1);
+            } else {
+
+                print_r("已经生成图片: ".$book['id']."       ".date("y-m-d H:i:s")."\n");
+            }
+
+        }
+
+        Log::info("======章节图片生成生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======章节图片生成生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+}

+ 146 - 0
app/Console/Commands/ChapterOrderTotal.php

@@ -0,0 +1,146 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+use Redis;
+use Log;
+class ChapterOrderTotal extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:cot {--type=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新章节订购统计';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $option = $this->option('type');
+        if(!$option){
+            $this->sub1();
+        }
+        if($option == 'cp'){
+            $this->cpChargeAndRewardV2();
+        }
+        if($option == 'order'){
+            $this->orderDayStat();
+        }
+    }
+
+
+    private function sub1(){
+        $start = date('Y-m-d',time()-86400);
+        $end = date('Y-m-d');
+        $sql = 'call cp_data_temp("'.$start.'","'.$end.'");';
+        DB::connection('chapter_order_mysql')->select($sql);
+        $bids = DB::table('book_configs')->select('bid')->get();
+        $data = [];
+        $day = date('Y--m-d',time()-86400);
+        foreach ($bids as $book){
+            $fee = Redis::hget('wap:chapterandbookorder:bid:'.$book->bid,$day);
+            if(!$fee) $fee = 0;
+            $data[] = ['bid'=>$book->bid,'day'=>$day,'fee'=>$fee,'created_at'=>date('Y-m-d H:i:s'),'updated_at'=>date('Y-m-d H:i:s')];
+            if(count($data) == 100){
+                DB::table('book_order_statistical')->insert($data);
+                $data = [];
+            }
+            Redis::hdel('wap:chapterandbookorder:bid:'.$book->bid,$day);
+        }
+        DB::table('book_order_statistical')->insert($data);
+        $end2 = $start.' 23:59:59';
+
+        $sql2 = 'call chapter_orders("'.$start.'","'.$end2.'");';
+        DB::connection('chapter_order_mysql')->select($sql2);
+    }
+
+
+    private function cpChargeAndReward(){
+        $date = date('Y-m-d',time()-86400);
+        $start_date = $date;
+        $end_date = date('Y-m-d');
+        $sql_format = "select bid,date(created_at) as date,sum(charge_balance) as sum_charge_balance ,sum(reward_balance) as sum_reward_balance from book_orders where created_at >'%s' AND created_at <'%s' GROUP by bid,date(created_at)";
+        echo sprintf($sql_format,$start_date,$end_date);
+        $book = DB::select(sprintf($sql_format,$start_date,$end_date));
+        foreach ($book as $v){
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('charge_balance',(int)$v->sum_charge_balance);
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('reward_balance',(int)$v->sum_reward_balance);
+        }
+
+        $sql = "select bid,date,sum(sum_charge_balance) as sum_charge_balance, sum(sum_reward_balance) as sum_reward_balance from sub_bak5 where date='%s'  GROUP by bid,date";
+        $chapter = DB::connection('chapter_order_mysql')->select(sprintf($sql,$date));
+        foreach ($chapter as $v){
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('charge_balance',(int)$v->sum_charge_balance);
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('reward_balance',(int)$v->sum_reward_balance);
+        }
+    }
+
+
+    private function cpChargeAndRewardV2(){
+        $date = date('Y-m-d',time()-86400);
+        $max_bid_info = DB::table('books')->select('id')->orderBy('id','desc')->first();
+        $max_bid = $max_bid_info->id;
+        $start_date = $date;
+        $end_date = date('Y-m-d');
+        $sql_format = "select bid,date(created_at) as date,sum(charge_balance) as sum_charge_balance ,sum(reward_balance) as sum_reward_balance from book_orders where created_at >'%s' AND created_at <'%s' GROUP by bid,date(created_at)";
+
+        $book = DB::select(sprintf($sql_format,$start_date,$end_date));
+        foreach ($book as $v){
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('charge_balance',(int)$v->sum_charge_balance);
+            DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->date)->increment('reward_balance',(int)$v->sum_reward_balance);
+        }
+        $sql = "select bid,date,sum(sum_charge_balance) as sum_charge_balance, sum(sum_reward_balance) as sum_reward_balance from sub_bak5 where date='%s' and bid=%s";
+        for($i =0;$i <= $max_bid ;$i++){
+            $temp = DB::connection('chapter_order_mysql')->select(sprintf($sql,$date,$i));
+            $temp = $temp[0];
+            if($temp->bid){
+                DB::table('book_order_statistical')->where('bid',$i)->where('day',$date)->increment('charge_balance',(int)$temp->sum_charge_balance);
+                DB::table('book_order_statistical')->where('bid',$i)->where('day',$date)->increment('reward_balance',(int)$temp->sum_reward_balance);
+            }
+        }
+
+    }
+
+    private function orderDayStat(){
+        DB::table('order_day_stats')->select('id', 'distribution_channel_id', 'date')->where('date',date('Y-m-d',time()-86400))->orderBy('id')->chunk(1000, function ($res) {
+            foreach ($res as $v) {
+                $chapter_sql = "select sum(sum_fee) as sum_fee,sum(sum_charge_balance) as sum_charge_balance,sum(sum_reward_balance) as sum_reward_balance from sub_bak5 where distribution_channel_id=%s and date='%s'";
+                $chapter_data = DB::connection('chapter_order_mysql')->select(sprintf($chapter_sql,$v->distribution_channel_id,$v->date));
+
+                $update_sql = "update send_orders_stats set sum_fee=sum_fee+".(int)$chapter_data[0]->sum_fee.',sum_charge_balance=sum_charge_balance+'.(int)$chapter_data[0]->sum_charge_balance.',sum_reward_balance=sum_reward_balance+'.(int)$chapter_data[0]->sum_reward_balance.' where id='.$v->id;
+                DB::update($update_sql);
+
+                $end_date = date('Y-m-d',strtotime($v->date)+86400);
+                $book_sql = "select sum(fee) as sum_fee,sum(charge_balance) as sum_charge_balance,sum(reward_balance) as sum_reward_balance from book_orders where distribution_channel_id={$v->distribution_channel_id} and created_at >='{$v->date}' and created_at < '{$end_date}'";
+                $chapter_data = DB::select($book_sql);
+
+                $update_sql = "update send_orders_stats set sum_fee=sum_fee+".(int)$chapter_data[0]->sum_fee.',sum_charge_balance=sum_charge_balance+'.(int)$chapter_data[0]->sum_charge_balance.',sum_reward_balance=sum_reward_balance+'.(int)$chapter_data[0]->sum_reward_balance.' where id='.$v->id;
+                DB::update($update_sql);
+            }
+        });
+    }
+
+}

+ 47 - 0
app/Console/Commands/CheckAndSend.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\TemplateCustomSendService;
+class CheckAndSend extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CheckAndSend';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+    private function start(){
+        TemplateCustomSendService::toCheckAndSendTemplateMsg();
+
+        TemplateCustomSendService::toCheckAndSendCustomMsg();
+    }
+}

+ 104 - 0
app/Console/Commands/CheckBookCover.php

@@ -0,0 +1,104 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands;
+
+use App\Modules\Book\Models\BookConfig;
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use GuzzleHttp\Client;
+use Illuminate\Console\Command;
+use Log;
+
+class CheckBookCover extends Command
+{
+    /**
+     * 执行命令 检查图书封面
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'check_book_cover_status';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '检查图书封面';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        Log::info('CheckBookCover start command');
+        $this->loadBookCoverInfo();
+        Log::info('CheckBookCover end command');
+    }
+
+    function loadBookCoverInfo()
+    {
+        $pageCount = 0; //当前的页数(默认从0开始)
+        $pageSize = 200;//每页的条数
+        $totalCount = BookConfig::getBooksCount(); //总条数
+        $totalPageCount = Ceil($totalCount / $pageSize); ////总页数
+        Log::info('CheckBookCover totalCount is  ' . $totalCount);
+        Log::info('CheckBookCover totalPageCount is  ' . $totalPageCount);
+        $errorBookCoverArray = [];
+        $client = new Client(['timeout' => 3.0,]);
+        while ($pageCount < $totalPageCount) {
+            Log::info('CheckBookCover currentPageCount is: ' . $pageCount);
+            $books = BookConfig::getBookCoverInfos(false, $pageSize, $pageCount);
+            foreach ($books as $bookItem) {
+                $coverUrl = $bookItem->cover;
+                try {
+                    $response = $client->request('get', $coverUrl);
+                    $resultCode = $response->getStatusCode();
+                    //成功
+                    if ($resultCode == 200 || $resultCode == 302) {
+
+                    } else {
+                        Log::info('CheckBookCover load error');
+                        $errorBookCoverArray[] = $bookItem;
+                    }
+                } catch (\Exception $e) {
+                    Log::info('CheckBookCover load error');
+                    $errorBookCoverArray[] = $bookItem;
+                }
+            }
+            $pageCount++;
+        }
+
+        if ($errorBookCoverArray) {
+            Log::info('CheckBookCover need sendEmail');
+            $this->sendEmail($errorBookCoverArray);
+        } else {
+            Log::info('CheckBookCover not need sendEmail');
+        }
+    }
+
+    function sendEmail($errorBookCoverArray)
+    {
+        Log::info('CheckBookCover start sendEmail');
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $content = "<table border='1' cellpadding='10' cellspacing='0'><tr><td align='center'>id</td><td align='center'>书名</td><td align='center'>作者</td></tr>";
+        foreach ($errorBookCoverArray as $item) {
+            $content .= "<tr><td align='center'>{$item->bid}</td><td align='center'>{$item->book_name}</td><td align='center'>{$item->author}</td></tr>";
+        }
+        $content .= "</table>";
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user, ['subject' => date("Y-m-d", time()) . "追书云错误封面的书籍信息", 'body' => $content]);
+    }
+}

+ 47 - 0
app/Console/Commands/CheckOfficialAccountTemplate.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Http\Controllers\Manage\OfficialAccount\WeChatToolsController;
+class CheckOfficialAccountTemplate extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CheckOfficialAccountTemplate';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '检查公众号模板';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->CheckOfficialAccountTemplate();
+    }
+
+    public function CheckOfficialAccountTemplate(){
+    	$weChatToolsController = new WeChatToolsController();
+        $weChatToolsController->check_official_account_templates();
+    }
+}

+ 88 - 0
app/Console/Commands/CheckZsySiteStatus.php

@@ -0,0 +1,88 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: qincp
+ * Date: 2019/1/7
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands;
+
+use App\Modules\Channel\Models\Channel;
+use App\Modules\Channel\Models\ChannelUser;
+use App\Modules\OfficialAccount\Models\OfficialAccount;
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use Log;
+
+class CheckZsySiteStatus extends Command
+{
+    /**
+     * 执行命令 检查站点信息
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'check_zsy_site_status';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '检查网读云站点信息';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        Log::info('CheckZsySiteStatus start command');
+        $start_date = date("Y-m-d", strtotime("-1 day"));
+        $end_date = date("Y-m-d");
+        $params = compact('start_date', 'end_date');
+        //站点信息
+        $result = Channel::getChannelInfoList($params, true);
+        //服务号信息
+        $officialAccounts = OfficialAccount::getInfoList($params);
+        //账号数
+        $accountCount = ChannelUser::getCount($params);
+
+        if ($result) {
+            $this->sendEmail($result, $officialAccounts, $accountCount);
+        } else {
+            Log::info('CheckZsySiteStatus not need sendEmail');
+        }
+    }
+
+    function sendEmail($result, $officialAccounts, $accountCount)
+    {
+        Log::info('CheckZsySiteStatus start sendEmail');
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $content = "<table border='1' cellpadding='10' cellspacing='0' style='float: left'><tr><td align='center'>序号</td><td align='center'>站点id</td><td align='center'>公司名称</td></tr>";
+        $siteIndex = 0;
+        foreach ($result as $item) {
+            $siteIndex++;
+            $content .= "<tr><td align='center'>{$siteIndex}</td><td align='center'>{$item->id}</td><td align='center'>{$item->company_name}</td></tr>";
+        }
+        $content .= "</table>";
+
+        $content .= "<table border='1'  style='float: left;margin-left: 35px' cellpadding='10' cellspacing='0'><tr><td align='center'>序号</td><td align='center'>站点id</td><td align='center'>服务号名称</td><td align='center'>主体</td></tr>";
+        $officialAccountIndex = 0;
+        foreach ($officialAccounts as $item) {
+            $officialAccountIndex++;
+            $content .= "<tr><td align='center'>{$officialAccountIndex}</td><td align='center'>{$item->distribution_channel_id}</td><td align='center'>{$item->nickname}</td><td align='center'>{$item->principal_name}</td></tr>";
+        }
+        $content .= "</table>";
+
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user, ['subject' => date("Y-m-d", time()) . "网读云昨天新增站点" . $siteIndex . "个,账号" . $accountCount . "个,服务号" . $officialAccountIndex . "个", 'body' => $content]);
+    }
+}

+ 46 - 0
app/Console/Commands/CpcAdvertise/AutoWithdraw.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands\CpcAdvertise;
+
+use App\Modules\Book\Services\SuperiorHistoryBookService;
+use DB;
+use Illuminate\Console\Command;
+
+class AutoWithdraw extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CpcAdvertise:AutoWithdraw';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'cpc广告自动提现';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+
+
+    }
+}

+ 52 - 0
app/Console/Commands/CpcAdvertise/CpcBillTasks.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace App\Console\Commands\CpcAdvertise;
+
+use App\Modules\Book\Services\SuperiorHistoryBookService;
+use App\Modules\CpcAdvertise\Services\ChannelBillsService;
+use App\Modules\CpcAdvertise\Services\CpcChannelStatsService;
+use DB;
+use Illuminate\Console\Command;
+
+class CpcBillTasks extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CpcAdvertise:bill_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '广告结算';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        //$date = date('Y-m-d',strtotime('-2 day'));
+        for($i=12;$i>=2;$i--){
+            $date = date('Y-m-d',strtotime('-'.$i.' day'));
+            ChannelBillsService::generate_bills($date);
+        }
+
+    }
+}

+ 48 - 0
app/Console/Commands/CpcAdvertise/MonthlyStatsTasks.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Console\Commands\CpcAdvertise;
+
+use App\Modules\Book\Services\SuperiorHistoryBookService;
+use App\Modules\CpcAdvertise\Services\ChannelBillsService;
+use App\Modules\CpcAdvertise\Services\CpcChannelStatsService;
+use DB;
+use Illuminate\Console\Command;
+
+class MonthlyStatsTasks extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CpcAdvertise:generate_month_data';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '广告结算';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $start_time = date('Y-m-01',strtotime('-1 month'));
+        $end_time = date('Y-m-d',strtotime(date('Y-m-01').' -1 day'));
+        ChannelBillsService::generateMonthData($start_time,$end_time);
+    }
+}

+ 94 - 0
app/Console/Commands/CustomMsg/CustomMsgStrategyAutoSend.php

@@ -0,0 +1,94 @@
+<?php
+
+namespace App\Console\Commands\CustomMsg;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+use App\Modules\OfficialAccount\Models\CustomMsgStrategy;
+use Illuminate\Console\Command;
+use DB;
+class CustomMsgStrategyAutoSend extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'auth_send_custom_msg_by_strategy';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '根据客服消息策略生成客服消息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //每个小时跑一次,对应这个小时内所有需要发的内容,生成客服消息
+        $hour_begin = date('H:00:00');
+        $hour_end = date('H:59:59');
+        $strategies = CustomMsgStrategy::whereNull('deleted_at')
+            ->where('status',1)
+            ->where(function ($query) {
+                $query->where('last_send_date','<',date('Y-m-d 00:00:00'))
+                    ->orWhereNull('last_send_date');
+            })
+            ->whereBetween('send_time',[$hour_begin,$hour_end])
+            ->select([
+                'id',
+                'appid',
+                'name',
+                'send_time',
+                'content',
+                'description',
+                'book_name',
+                'chapter_name',
+                'redirect_url',
+                'subscribe_time',
+                'sex',
+                'balance',
+                'order_type',
+                'category_id',
+                'is_full_send',
+                'distribution_channel_id',
+                'status',
+                'batch_order_sn',
+                'custom_type',
+            ])
+            ->get()
+        ;
+        $strategies = json_decode(json_encode($strategies), true);
+        foreach ($strategies as $strategy){
+            $strategy['status']=1;
+            $strategy_id = $strategy['id'];
+            unset($strategy['id']);
+            $strategy['send_time']=date('Y-m-d ').$strategy['send_time'];
+            //先判断在发送时间段1小时以内,有没有发起过相同的模板消息,如果有发送过,就提示用户已经创建过相同模板消息,不创建新的模板消息
+            $isSendCustomer = CustomMsgService::isSendCustomerAtSameTime($strategy);
+            if (!empty($isSendCustomer)) {
+                \Log::info('isSendCustomerAtSameTime:' . $strategy['distribution_channel_id']);
+            } else {
+                CustomMsgStrategy::where('id',$strategy_id)->update(['last_send_date' => date('Y-m-d H:i:s')]);
+                $customMsgService = CustomMsgService::addCustomSendMsgs($strategy);
+
+
+            }
+        }
+
+
+    }
+}

+ 46 - 0
app/Console/Commands/CustomSignPush.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class CustomSignPush extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CustomSignPush';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '签到智能推送';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->customSignPush();
+    }
+
+    public function customSignPush(){
+        CustomMsgService::SmartPush('sign_push');
+    }
+}

+ 46 - 0
app/Console/Commands/CustomSubscribePush.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class CustomSubscribePush extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'CustomSubscribePush';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '关注智能推送';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->customSubscribePush();
+    }
+
+    public function customSubscribePush(){
+        CustomMsgService::SmartPush('subscribe_push');
+    }
+}

+ 61 - 0
app/Console/Commands/DistributionStats/WeeklyDailyStats.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ 渠道周报数据
+ */
+
+namespace App\Console\Commands\DistributionStats;
+
+use Log;
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Models\TempForceSubscribeUsers;
+use App\Modules\OfficialAccount\Services\MsgService;
+use App\Modules\SendOrder\Services\SendOrderStatisticsService;
+use App\Modules\Channel\Models\Channel;
+use DB;
+
+class WeeklyDailyStats extends Command
+{
+    /**
+     * 执行命令  WeeklyDailyStats 123
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'WeeklyDailyStats {channel_id}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '维护渠道周报数据';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        ini_set('memory_limit', '1024M');
+        print_r('memory_used:'.memory_get_usage()."\n");
+        print_r("======维护渠道周报数据【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        $distribution_channel_id = $this->argument('channel_id');
+        if($distribution_channel_id != 'all'){
+       		\Log::info('start_getWeeklySendOrderStatistics:'.$distribution_channel_id);
+        	SendOrderStatisticsService::getWeeklySendOrderStatistics($distribution_channel_id);
+        }else{
+        	$distribution_channels = Channel::getAllChannels();
+        	// 渠道列表
+        	foreach($distribution_channels as $distribution_channel){
+        		$distribution_channel_id = $distribution_channel->id;
+        		\Log::info('start_getWeeklySendOrderStatistics:'.$distribution_channel_id);
+        		SendOrderStatisticsService::getWeeklySendOrderStatistics($distribution_channel_id);
+        	}
+        }
+        
+        print_r("======维护渠道周报数据 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r('memory_used:'.memory_get_usage()."\n");
+    }
+}

+ 59 - 0
app/Console/Commands/DownPic.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/24
+ * Time: 上午11:48
+ */
+
+namespace App\Console\Commands;
+
+use Log;
+use App\Modules\Finance\Models\Bill;
+use GuzzleHttp;
+use Illuminate\Console\Command;
+use Storage;
+
+class DownPic extends Command
+{
+
+
+    /**
+     * 执行命令   php artisan bill_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'down_pic';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '下载图片';
+
+
+    public function handle() {
+        $client = new GuzzleHttp\Client();
+
+        $fp  = fopen(storage_path("app/abc.txt"), 'r');
+        $str = fread($fp,filesize(storage_path("app/abc.txt")));
+        $arraylist= explode("\n",$str);
+        for($i=0;$i<count($arraylist);$i++) //把它们全部输出来
+        {
+            if(!empty($arraylist[$i])) {
+                echo $arraylist[$i]."     \n";
+                $data = $client->request('GET', $arraylist[$i])->getBody()->getContents();
+                $filename = str_replace("http://cdn-novel.weituibao.com/", "", $arraylist[$i]);
+                echo $filename."     \n";
+
+                Storage::disk('local')->put($filename, $data);
+            }
+        }
+    }
+
+
+
+}

+ 214 - 0
app/Console/Commands/FailOrderAlert.php

@@ -0,0 +1,214 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\Subscribe\Services\OrderService;
+use Redis;
+use App\Libs\SMS;
+use Log;
+use DB;
+use App\Jobs\SendTexts;
+class FailOrderAlert extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'foa {--qrcode}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '失败订单预警';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $options = $this->option('qrcode');
+        if($options){
+            return $this->forceSubscribeErrorAlert();
+        } else{
+            $this->tooLongNoOrderAlert();
+            return  $this->start();
+
+        }
+    }
+
+    private function start(){
+        if(!$this->isCanAlert()) return 1;
+        $sorce = $this->getPaySource();
+        if(!$sorce){
+            return false;
+        }
+        foreach ($sorce as $v){
+            $is_all_fail= $this->isAllFail($v->source);
+            $too_long = $this->lastOrderTooLong();
+            $content = '';
+            if($is_all_fail){
+                $content = '订单预警,'.$v->source.'通道最近20个订单都是未支付订单,尽快排查';
+            }
+
+            if($too_long){
+                $content = $v->source.'通道最近半小时没有产生一条订单,尽快排查';
+            }
+            if(!$content) return 2;
+
+            $phone_arr = ['15868100210','15088790066','13858057394','18668029091','18668420256'];
+            //$phone_arr = ['18668029091'];
+            foreach ($phone_arr as $phone){
+                $this->sendAndRecord(1,$phone,$content);
+            }
+            $key = 'distribution_channel_id:orderalert';
+            $field = 'sendalert';
+            Redis::hset($key,$field,time());
+        }
+
+        return 3;
+
+    }
+
+    private function forceSubscribeErrorAlert(){
+        $errors = Redis::SMEMBERS('force_subscribe_qrcode:error');
+        if(!$errors){
+            return false;
+        }
+
+        $res = [];
+        foreach ($errors as $value){
+            $temp = explode('_',$value);
+            $res[$temp[0]][] = $temp[1];
+        }
+        $phone_arr = ['15868100210','15088790066','13858057394','18668029091','18668420256'];
+        //$phone_arr = ['18668029091'];
+        if($res){
+            foreach ($res as $k=>$v){
+                if(count($v) >= 5){
+                    $content = 'appid='.$k.'的公众号获取强关二维码出问题了!!,一分钟之内出现'.count($v).'次';
+                    foreach ($phone_arr as $phone){
+                        SMS::send($phone,$content);
+                    }
+                    //break;
+                }
+            }
+        }
+        Redis::srem('force_subscribe_qrcode:error',$errors);
+        return false;
+    }
+
+    private  function tooLongNoOrderAlert(){
+        $last = DB::table('orders')->orderBy('id','desc')->first();
+        if(time()-strtotime($last->created_at) >= 150){
+            $phone_arr = ['15868100210','15088790066','13858057394','18668029091','18668420256'];
+            //$phone_arr = ['18668029091'];
+            $content = '订单预警,最近两分半没有产生一条订单,尽快排查';
+            foreach ($phone_arr as $phone){
+                echo SMS::send($phone,$content);
+            }
+        }
+    }
+
+    private function getAllChannel(){
+        return OrderService::getAllChannelId();
+    }
+
+    private function getPaySource(){
+        $sql = 'select distinct pay_merchant_id from distribution_channels where pay_merchant_id <>0';
+        $res = DB::select($sql);
+        $id_array = [];
+        if($res){
+            foreach ($res as $v){
+                $id_array[] = $v->pay_merchant_id;
+            }
+        }
+        $ssql = 'select distinct source from pay_merchants where id in('.implode(',',$id_array).')';
+        $source = DB::select($ssql);;
+        return $source;
+    }
+    /**
+     * 最近20订单是否全部失败
+     * @param $channel
+     * @param int $num
+     * @return bool
+     */
+    private  function isAllFail($source,$num=20){
+        $order = OrderService::getLatestOrderByChannleId($source,$num);
+
+        if(!$order)  return false;
+        if($order && count($order) < $num){
+            return false;
+        }
+        foreach ($order as $val){
+            if($val->status == 'PAID'){
+                return false;
+            }
+
+        }
+        return true;
+    }
+
+    /**
+     * 最后一条订单距离现在是否超过半小时
+     * @return bool
+     */
+    private function lastOrderTooLong(){
+        $order = OrderService::getLastOrder();
+        if(time()-strtotime($order->created_at) > 1800){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 是否可以发送预警
+     * @param $channel
+     * @return bool
+     */
+    private function isCanAlert(){
+        $key = 'distribution_channel_id:orderalert';
+        $field = 'sendalert';
+        $res = Redis::hget($key,$field);
+        if($res && (time()-$res) < 1800 ){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 发送预警,并记录
+     * @param $channel_info
+     * @param $content
+     * @return bool
+     */
+    private function sendAndRecord($channel,$phone,$content){
+        if(empty($phone)){
+            return false;
+        }
+        $status = SMS::send($phone,$content);
+
+        $record = json_encode([
+            'phone'=>$phone,
+            'status'=>$status,
+            'time'=>time()
+        ]);
+        $key = 'distribution_channel_id:orderalert:record';
+        Redis::rpush($key,$record);
+    }
+}

+ 161 - 0
app/Console/Commands/FailOrderAlertV2.php

@@ -0,0 +1,161 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\Subscribe\Services\OrderService;
+use Redis;
+use App\Libs\AliSMS;
+use Log;
+use DB;
+use App\Modules\Subscribe\Models\Order;
+
+class FailOrderAlertV2 extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'foav2';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '失败订单预警';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->payAlert();
+    }
+
+    private function payAlert()
+    {
+        $pay_ids = $this->getPayId();
+        if(!$pay_ids){
+            return '';
+        }
+        foreach ($pay_ids as $pay_id){
+            $this->payAlertOne($pay_id);
+        }
+        return '';
+    }
+
+    private function payAlertOne($pay_id)
+    {
+
+        $phone_arr = ['15868100210','15088790066','13858057394','18668029091','18668420256','15869177764'];
+        $pay_info = Redis::hgetall('pay_merchant:'.$pay_id);
+        $is_need_alert = false;
+        $ntime = time();
+        $time_str = 180;   
+        // 10min 15min 1.5min 3min 未支付的订单报警规则  96/103 倍道  97树羽
+        $alert_time_diff = ['44'=>600,'46'=>3600,'43'=>90,'101'=>3600,'55'=>300,'96'=>180,'103'=>180,'104'=>180,'105'=>180,'108'=>180,'109'=>180,'123'=>180,'124'=>180,'130'=>180];
+        if($pay_info)
+        {
+            $last_alert_time = isset($pay_info['last_alert_time']) ? (int)$pay_info['last_alert_time'] : 0;//上次报警时间
+            if($ntime - $last_alert_time > 180)//2小时内不重复报警
+            {
+                $unpaid_num = isset($pay_info['unpaid_num']) ?  (int)$pay_info['unpaid_num'] : 0;
+                $last_create_time = isset($pay_info['last_create_time']) ?  (int)$pay_info['last_create_time'] : 0;
+
+                $order_num = 20;
+                if($unpaid_num  >= $order_num)//超过30条都是失败订单报警
+                {
+                    $is_need_alert = true;
+                    $content = '订单预警!!!支付通道: '.$pay_id.',最近'.$order_num.'个订单都是未支付订单,尽快排查。。';
+                    $template_type = 'order_remind';
+                    
+                    $back_pay = DB::table('pay_merchants')
+                        ->where('name','BD_BACK_UP_MAIN')
+                        ->where('is_enabled',1)
+                        ->select('id')->orderBy('id','desc')->first();
+                    if($back_pay){
+                        DB::table('distribution_channels')->where('pay_merchant_id',$pay_id)->update([
+                            'pay_merchant_id'=>$back_pay->id,
+                            'updated_at'=>date('Y-m-d H:i:s')
+                        ]);
+
+                        DB::table('pay_merchants')->where('id',$pay_id)->update(['name'=>'BD_DEFAULT2','updated_at'=>date('Y-m-d H:i:s')]);
+                        DB::table('pay_merchants')->where('id',$back_pay->id)->update(['name'=>'BD_DEFAULT','updated_at'=>date('Y-m-d H:i:s')]);
+
+                        $param = ['pay_id'=>$pay_id,'new_pay_id' => $back_pay->id];
+                        foreach ($phone_arr as $phone){
+                            $this->sendSms($phone, 'pay_channel_change',$param);
+                        }
+
+                    }else{
+                       $param = ['pay_id'=>$pay_id];
+                        foreach ($phone_arr as $phone){
+                            $this->sendSms($phone, $template_type,$param);
+                        } 
+                    }
+                }
+
+                /*if(in_array($pay_id,[41,43,46])  && $last_create_time && ($ntime - $last_create_time) > $time_str)
+                {
+                    $is_need_alert = true;
+                    $content = '支付通道: '.$pay_id.' ,最近'.$time_str.'秒内没有产生一条订单,尽快排查';
+                    $template_type = 'order_halfhour_remind';
+                    $param = ['pay_id'=>$pay_id];
+                    foreach ($phone_arr as $phone){
+                        $this->sendSms($phone, $template_type,$param);
+                    }
+                }*/
+                if(isset($alert_time_diff[$pay_id])  && $last_create_time && ($ntime - $last_create_time) > $alert_time_diff[$pay_id] ){
+                    $is_need_alert = true;
+                    $content = '支付通道: '.$pay_id.' ,最近'.$time_str.'秒内没有产生一条订单,尽快排查';
+                    $template_type = 'order_halfhour_remind';
+                    $param = ['pay_id'=>$pay_id];
+                    foreach ($phone_arr as $phone){
+                        $this->sendSms($phone, $template_type,$param);
+                    }
+                }
+
+                if($is_need_alert)//更新报警时间
+                {
+                    Redis::hset('pay_merchant:'.$pay_id,'last_alert_time',$ntime);
+                }
+            }
+        }
+    }
+
+    /**
+     * 发送预警
+     */
+    private function sendSms($phone, $template_type,$param){
+        if(empty($phone)){
+            return false;
+        }
+        return AliSMS::send($phone, $template_type,$param);
+    }
+
+    private function getPayId(){
+        $sql = 'select distinct pay_merchant_id from distribution_channels where pay_merchant_id <>0 and id !=14';
+        $res = DB::select($sql);
+        $id_array = [];
+        if($res){
+            foreach ($res as $v){
+                $id_array[] = $v->pay_merchant_id;
+            }
+        }
+        return $id_array;
+    }
+}

+ 48 - 0
app/Console/Commands/ForBiddenOfficialAccountRemind.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\OfficialAccountService;
+class ForBiddenOfficialAccountRemind extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'ForBiddenOfficialAccountRemind';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'ForBiddenOfficialAccountRemind';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        \Log::info("======公众号封号检测【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        $this->start();
+        \Log::info("======公众号封号检测【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+
+    public function start(){
+        OfficialAccountService::check_gzh_ban();
+    }
+}

File diff suppressed because it is too large
+ 263 - 0
app/Console/Commands/ForceUserActive.php


+ 148 - 0
app/Console/Commands/ForceUserActiveDetail.php

@@ -0,0 +1,148 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands;
+
+use App\Modules\Finance\Services\FinanceService;
+use Log;
+use Illuminate\Console\Command;
+use DB;
+use Redis;
+use App\Modules\Book\Services\BookSubscribleChapterService;
+
+class ForceUserActiveDetail extends Command
+{
+    /**
+     * 执行命令   php artisan force_user_active
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'force_user_active_detail';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日强关用户行为详细';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日强关用户行为详细生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======每日强关用户行为详细生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $_start = new \DateTime('2018-03-16');
+        $_end = new \DateTime('2018-03-17');
+
+        foreach (new \DatePeriod($_start, new \DateInterval('P1D'), $_end) as $d)
+        {
+
+            $date = $d->format('Y-m-d');
+            $start = $date;
+            $end = date('Y-m-d', strtotime($date) + 86400);
+
+            $offset = 0;
+            $limit = 10000;
+            $data = [];
+            $_m_data = [];
+
+            while (true) {
+
+                print_r("select send_order_id,uid,appid,unsubscribe_time,distribution_channel_id,created_at from force_subscribe_users where created_at > '{$start}' and created_at < '{$end}' limit $offset,$limit" . date("y-m-d H:i:s" . "\n"));
+                $users = DB::select("select send_order_id,uid,appid,unsubscribe_time,distribution_channel_id,created_at from force_subscribe_users where created_at > '{$start}' and created_at < '{$end}' limit $offset,$limit");
+                print_r("users_count:".count($users));
+                if (count($users) == 0) break;
+
+                foreach ($users as $user) {
+                    $is_unsub_in_one_day = false;
+                    $is_pay_in_one_day = false;
+
+                    $_read_data = [
+                        'date' => $date,
+                        'appid' => $user->appid,
+                        'uid' => $user->uid,
+                        'sub_time' => strtotime($user->created_at),
+                        'unsub_time' => strtotime($user->unsubscribe_time),
+                    ];
+
+                    $order = DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->first();
+                    if ($order) {
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400)//24小时内
+                        {
+                            $_read_data['recharge_time_in_one_day'] = strtotime($order->created_at);
+                            $is_pay_in_one_day = true;
+                        }
+
+                    }
+
+                    $one_day_time = strtotime($user->created_at) + 86400;
+                    if ($user->unsubscribe_time && strtotime($user->unsubscribe_time) < strtotime($user->created_at) + 86400)//24小时内取注
+                    {
+                        $is_unsub_in_one_day = true;
+                        $_read_data['is_unsub_in_one_day'] = 1;
+                    }
+
+                    $last_read_info = Redis::hget('book_base:' . $user->uid, 'last_read');
+
+                    $send_order = DB::table('send_orders')->where('id', $user->send_order_id)->first();
+                    if ($send_order && $send_order->book_id && $last_read_info) {
+                        $book = Redis::hget('book_read:' . $user->uid, $send_order->book_id);
+                        $book_info = explode('_', $book);
+
+                        $cid = $book_info[0];
+                        $vip_chapter = DB::table('chapters')->select(['sequence'])->where('bid', $send_order->book_id)->where('is_vip', 1)->orderby('sequence')->first();
+
+                        $read_last_free = DB::table('read_records')->where('bid', $send_order->book_id)->where('uid', $user->uid)->where('created_at', '<=', date('Y-m-d H:i:s', $one_day_time))->where('seq', $vip_chapter->sequence - 1)->first();
+
+                        $last_read_array = explode('_', $last_read_info);
+                        $last_read_time = $last_read_array[4];
+
+                        //$_read_data['last_read_time'] = $last_read_time;
+                        $_read_data['last_free_read_time'] = $read_last_free ? strtotime($read_last_free->created_at) : 0;
+
+                        $book_config = DB::table('book_configs')->select(['force_subscribe_chapter_seq','charge_type'])->where('bid', $send_order->book_id)->first();
+                        //订阅
+                        if($book_config->charge_type == 'CHAPTER') {
+                            $first_sub = DB::connection('chapter_order_mysql')->table('chapter_orders' . $user->uid % 512)->where('uid', $user->uid)->where('created_at', '<=', date('Y-m-d H:i:s', $one_day_time))->where('bid', $send_order->book_id)->orderBy('id', 'asc')->first();
+                            $_read_data['first_sub_time'] = $first_sub ? strtotime($first_sub->created_at) : 0;
+                        }
+
+                        if($book_config->charge_type == 'BOOK') {
+                            $_read_last_free = DB::table('read_records')->where('bid', $send_order->book_id)->where('uid', $user->uid)->where('seq', $vip_chapter->sequence - 1)->first();
+                            $_read_data['first_sub_time'] = $_read_last_free ? strtotime($_read_last_free->created_at) : 0;
+                        }
+                    }
+
+                    //第一次点击返回时间
+                    $back_info = DB::table('back_actives')->where('uid',$user->uid)->first();
+                    if($back_info)
+                    {
+                        $_read_data['first_click_back_time'] = strtotime($back_info->created_at);
+                    }
+                    $_read_data['created_at'] = date("Y-m-d H:i:s");
+                    DB::table('force_users_date_read')->insert($_read_data);
+                }
+
+                $offset = $offset + $limit;
+
+            }
+
+            Log::info("======每日强关用户行为详细生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+            print_r("======每日强关用户行为详细生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+
+
+        }
+    }
+}

+ 108 - 0
app/Console/Commands/IndividualOpPlatform/AddDeepReadRecords.php

@@ -0,0 +1,108 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\IndividualOpPlatform;
+
+use DB;
+use Illuminate\Console\Command;
+use Log;
+use Redis;
+
+
+class AddDeepReadRecords extends Command
+{
+    /**
+     * 执行命令   php artisan force_user_active
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'add_deep_read_records';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '个性化运行平台添加';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //章节订阅
+        for($i=0;$i<512;$i++) {
+            $res = DB::connection('chapter_order_read_mysql')
+                ->select("SELECT t.uid,t.bid,t.first_sub_time,(SELECT created_at FROM chapter_orders".$i." co1 WHERE co1.uid=t.uid
+ AND co1.bid=t.bid
+ AND (SELECT COUNT(*) FROM chapter_orders".$i." coo1
+ WHERE coo1.uid=co1.uid AND co1.bid=coo1.bid AND coo1.id<=co1.id)=30) as deep_sub_time,'CHAPTER_ORDER' as 'charge_type',NOW() as 'created_at',NOW() as 'updated_at'
+ FROM (SELECT * FROM (SELECT uid,bid,MIN(created_at) AS first_sub_time,count(id) as count FROM chapter_orders".$i." GROUP BY uid,bid HAVING count>=30) tmp
+					WHERE NOT EXISTS(SELECT 1 FROM deep_read_records WHERE deep_read_records.uid=tmp.uid AND deep_read_records.bid=tmp.bid)) t");
+            $to_insert = [];
+            foreach ($res as $item) {
+                $to_insert[] = array(
+                    'uid'=>$item->uid,
+                    'bid'=>$item->bid,
+                    'first_sub_time'=>$item->first_sub_time,
+                    'deep_sub_time'=>$item->deep_sub_time,
+                    'charge_type'=>$item->charge_type,
+                    'created_at'=>$item->created_at,
+                    'updated_at'=>$item->updated_at
+                );
+            }
+            //阅读记录插入订阅库
+            DB::connection('chapter_order_mysql')
+                ->table('deep_read_records')
+                ->insert($to_insert);
+            //阅读记录同步入主数据库
+            DB::table('deep_read_records')->insert($to_insert);
+        }
+        //单本订阅,无须筛选
+        /*$last_record_id = Redis::get('last_update_book_orders_id:');
+        $last_record_id = $last_record_id?intval($last_record_id):0;*/
+        //\Log::info('last_update_book_orders_id:'.$last_record_id);
+        //$current_max_id = $last_record_id;
+        /*DB::table("book_orders")
+            ->where('id','>',$last_record_id)
+            ->select(['id','uid','bid','created_at'])
+            ->groupBy('uid')
+            ->groupBy('bid')
+            ->orderBy('id')
+            ->chunk(1000,function ($res) use(&$current_max_id){
+                //$i=1;
+                $to_insert = [];
+                foreach ($res as $key=> $item){
+                    $to_insert[] = array(
+                        'uid'=>$item->uid,
+                        'bid'=>$item->bid,
+                        'first_sub_time'=>$item->created_at,
+                        'deep_sub_time'=>$item->created_at,
+                        'charge_type'=>'BOOK_ORDER',
+                        'created_at'=>date('Y-m-d H:i:s'),
+                        'updated_at'=>date('Y-m-d H:i:s')
+                    );
+                    if(($item->id)>$current_max_id){
+                        $current_max_id=$item->id;
+                    }
+                }
+                DB::table('deep_read_records')->insert($to_insert);
+            });*/
+        $sql = "INSERT INTO deep_read_records (`uid`,`bid`,`first_sub_time`,`deep_sub_time`,`charge_type`,`created_at`,`updated_at`) select `uid`, `bid`, `created_at` AS `first_sub_time`,`created_at`,'BOOK_ORDER',NOW(),NOW() AS `deep_sub_time`
+ from `book_orders` WHERE uid>0 AND created_at >= '".date('Y-m-d',strtotime('-1 day'))."'
+  group by `uid`, `bid` ON DUPLICATE KEY UPDATE `updated_at` = (SELECT NOW())";
+        DB::update($sql);
+        //Redis::set('last_update_book_orders_id:',$current_max_id);
+    }
+}
+
+

+ 33 - 0
app/Console/Commands/Inspire.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Illuminate\Foundation\Inspiring;
+
+class Inspire extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'inspire';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Display an inspiring quote';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->comment(PHP_EOL.Inspiring::quote().PHP_EOL);
+    }
+}

+ 119 - 0
app/Console/Commands/LatestCustomerMsg.php

@@ -0,0 +1,119 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Redis;
+use DB;
+use Hashids;
+
+class LatestCustomerMsg extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'LatestCustomerMsg';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'latest three days customer msg';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+    private function start()
+    {
+        Redis::del('latestcustomerinfo');
+        $sites = redisEnv('CUSTOM_CHAPTER_ORDER_SITES', '');
+        if (!$sites) return;
+        $sites = explode(',', $sites);
+        $result = \App\Modules\OfficialAccount\Models\CustomSendMsgs::where('send_time', '>=', date('Y-m-d H:i:s', time() - 15 * 60 - 3 * 86400))
+            ->where('send_time', '<=', date('Y-m-d H:i:s'))
+            ->whereIn('distribution_channel_id', $sites)
+            ->select('id', 'redirect_url', 'send_time')
+            ->get();
+        if ($result->isEmpty()) return;
+        foreach ($result as $item) {
+            if (!$item->redirect_url) continue;
+            $url_info = parse_url($item->redirect_url);
+            if (isset($url_info['path']) && isset($url_info['query'])) {
+                if (strpos('/reader', $url_info['path']) === false &&
+                    strpos('/yun', $url_info['path']) === false &&
+                    strpos('/detail', $url_info['path']) === false &&
+                    strpos('/custom_msgs_page', $url_info['path']) === false
+                ) {
+                    continue;
+                }
+                $bid = null;
+                if (strpos('/reader', $url_info['path']) !== false) {
+                    parse_str($url_info['query'], $param);
+                    if (!isset($param['bid'])) {
+                        continue;
+                    }
+                    if ($param['bid'] == 'undefined') continue;
+                    $bid_info = Hashids::decode($param['bid']);
+                    $bid = isset($bid_info[0]) ? $bid_info[0] : 0;
+                }
+
+                if (strpos('/custom_msgs_page', $url_info['path']) !== false) {
+                    $temp = urldecode($url_info['query']);
+                    $temp_info = parse_url($temp);
+                    parse_str($temp_info['query'], $param);
+                    if (!isset($param['bid'])) {
+                        continue;
+                    }
+                    if ($param['bid'] == 'undefined') continue;
+                    $bid_info = Hashids::decode($param['bid']);
+                    $bid = isset($bid_info[0]) ? $bid_info[0] : 0;
+                }
+
+                /*if (strpos('/detail',$url_info['path']) !== false) {
+                    parse_str($url_info['query'],$param);
+                    if (!isset($param['id'])) {
+                        continue;
+                    }
+                    if($param['id'] == 'undefined') continue;
+                    $bid_info = \Hashids::decode($param['id']);
+                    $bid = isset($bid_info[0])?$bid_info[0]:0;
+                }
+
+                if (strpos($url_info['path'],'/yun/') !== false) {
+                    $send_order_id = str_replace('/yun/','',$url_info['path']);
+                    $send_order_info = \App\Modules\SendOrder\Services\SendOrderService::getById($send_order_id);
+                    if($send_order_info){
+                        $bid = $send_order_info->book_id;
+                    }
+                }*/
+                if (!$bid) continue;
+
+                Redis::hset('latestcustomerinfo', $item->id, json_encode([
+                    'bid' => $bid,
+                    'send_time' => $item->send_time
+                ]));
+            }
+
+        }
+    }
+}

+ 46 - 0
app/Console/Commands/NoPayRemind.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class NoPayRemind extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'Pay:remind';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '未支付订单提醒';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->payRemind();
+    }
+
+    public function payRemind(){
+        CustomMsgService::sendUnpaid();
+    }
+}

+ 71 - 0
app/Console/Commands/OfficialAccountBillsTask.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\Trade\Services\OrderService;
+use DB;
+use Illuminate\Console\Command;
+
+class OfficialAccountBillsTask extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'official_account_bills_task  {--start=} {--end=} {--day=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '服务号每日充值统计';
+
+
+    public function handle()
+    {
+        $start = $this->option('start');
+        $end = $this->option('end');
+        $day = $this->option('day');
+        if($start && $end){
+             $this->start_scope($start,$end);
+        }elseif($day){
+            $this->start_day($day);
+        }else{
+            $this->start();
+        }
+    }
+
+    private function start(){
+        $yesterday = date('Y-m-d', strtotime(date("Y-m-d") . " -1 day"));
+        //echo '$yesterday'.$yesterday.PHP_EOL;
+        $data = OrderService::getRechargeAmountGroupByOfficial($yesterday);
+        DB::table('official_account_bills')->insert($data);
+    }
+
+
+    private function start_scope($start,$end){
+
+        if(strtotime($start) >= strtotime($end)){
+            return false;
+        }
+        $temp_start = $start;
+        while (true){
+            $this->start_day($temp_start);
+            if($temp_start == $end){
+                break;
+            }
+            $temp_start = date('Y-m-d',strtotime($temp_start)+86400);
+        }
+        return 1;
+    }
+
+
+    private function start_day($day){
+        //echo $day.PHP_EOL;
+        $data = OrderService::getRechargeAmountGroupByOfficial($day);
+        DB::table('official_account_bills')->insert($data);
+    }
+
+}

+ 86 - 0
app/Console/Commands/OfficialAccountStat/OfficialAccountForbiddenStatus.php

@@ -0,0 +1,86 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\OfficialAccountStat;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use DB;
+use Illuminate\Console\Command;
+use Log;
+
+class OfficialAccountForbiddenStatus extends Command
+{
+    /**
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'check_official_account_forbidden_status';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '公众号每日被封号的情况';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        Log::info('check_official_account_forbidden_status start command');
+        $date = date('Y-m-d', strtotime('-1 day'));
+        $table_name = 'forbidden_official_account_records';
+        $result = DB::table($table_name)->where('date', $date)->orderBy('created_at')->get();
+        if ($result && count($result) > 0) {
+            Log::info('check_official_account_forbidden_status need sendEmail');
+            $this->sendEmail($result);
+        } else {
+            Log::info('check_official_account_forbidden_status not need sendEmail');
+        }
+    }
+
+    function sendEmail($result)
+    {
+        Log::info('check_official_account_forbidden_status start sendEmail');
+        $to_user = array(
+            ['address' => 'songdb@iqiyoo.com', 'name' => '宋栋波'],
+            ['address' => 'zhaojp@yqsd.net', 'name' => '赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $content = "<table border='1' cellpadding='10' cellspacing='0'>
+        <tr>
+            <td align='center'>日期</td>
+            <td align='center'>站点id</td>
+            <td align='center'>appid</td>
+            <td align='center'>服务号名称</td>
+            <td align='center'>公司名称</td>
+            <td align='center'>封号时间</td>
+       </tr>";
+
+        $index = 0;
+        foreach ($result as $item) {
+            $index++;
+            $content .= "<tr>
+                            <td align='center' nowrap='nowrap'>{$item->date}</td>
+                            <td align='center' nowrap='nowrap'>{$item->distribution_channel_id}</td>
+                            <td align='center' nowrap='nowrap'>{$item->appid}</td>
+                            <td align='center' nowrap='nowrap'>{$item->nickname}</td>
+                            <td align='center' nowrap='nowrap'>{$item->company_name}</td>
+                            <td align='center' nowrap='nowrap'>{$item->forbbidden_time}</td>
+                        </tr>";
+        }
+        $content .= "</table>";
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user, ['subject' => date("Y-m-d", time()) . "网读昨天封号" . $index . "个", 'body' => $content]);
+    }
+}

+ 214 - 0
app/Console/Commands/OfficialAccountStat/SubUserRecharge.php

@@ -0,0 +1,214 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/11/20
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\OfficialAccountStat;
+
+use Log;
+use Illuminate\Console\Command;
+use DB;
+
+class SubUserRecharge extends Command
+{
+    /**
+     * 执行命令   php artisan force_user_active
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sub_user_recharge';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '强关粉丝充值统计';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        /**
+         * CREATE TABLE `sub_user_recharge_stat` (
+        `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+        `date` date DEFAULT NULL,
+        `appid` varchar(255) DEFAULT NULL,
+        `fans_num` int(11) DEFAULT NULL,
+        `order_sum_in_one_day` decimal(11,2) DEFAULT NULL,
+        `order_sum_in_three_day` decimal(11,2) DEFAULT NULL,
+        `unsub_user_num_in_one_month` int(11) DEFAULT NULL,
+        `order_sum_in_one_month` decimal(11,2) DEFAULT NULL,
+        `unsub_user_num_in_two_month` int(11) DEFAULT NULL,
+        `pay_user_num_in_two_month` int(11) DEFAULT NULL,
+        `order_sum_in_two_month` decimal(11,2) DEFAULT NULL,
+        `unsub_user_num_in_three_month` int(11) DEFAULT NULL,
+        `order_sum_in_three_month` decimal(11,2) DEFAULT NULL,
+        `pay_user_num_in_three_month` int(11) DEFAULT NULL,
+        `created_at` datetime DEFAULT NULL,
+        `updated_at` datetime DEFAULT NULL,
+        `distribution_channel_id` int(11) DEFAULT NULL,
+        `gzh_name` varchar(255) DEFAULT NULL,
+        `distribution_channel_name` varchar(255) DEFAULT NULL,
+        PRIMARY KEY (`id`)
+        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+         *
+         *
+        update sub_user_recharge_stat,distribution_channels,official_accounts set sub_user_recharge_stat.distribution_channel_id = distribution_channels.id,sub_user_recharge_stat.distribution_channel_name=distribution_channels.nickname,sub_user_recharge_stat.gzh_name = official_accounts.nickname  where sub_user_recharge_stat.appid = official_accounts.appid and official_accounts.distribution_channel_id = distribution_channels.id
+        select distribution_channel_id,gzh_name,distribution_channel_name,date,fans_num,order_sum_in_one_day,order_sum_in_three_day,unsub_user_num_in_one_month,order_sum_in_one_month,unsub_user_num_in_two_month,pay_user_num_in_two_month,order_sum_in_two_month,unsub_user_num_in_three_month,pay_user_num_in_three_month,order_sum_in_three_month from sub_user_recharge_stat
+         */
+        print_r("======强关粉丝充值统计生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======强关粉丝充值统计生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $_start = new \DateTime('2017-12-12');
+        $_end = new \DateTime('2018-02-18');
+
+        foreach (new \DatePeriod($_start, new \DateInterval('P1D'), $_end) as $d)
+        {
+
+            $date = $d->format('Y-m-d');
+            $start = $date;
+            $end = date('Y-m-d', strtotime($date) + 86400);
+
+            $offset = 0;
+            $limit = 13000;
+            $data = [];
+            $_m_data = [];
+
+            while (true) {
+
+                print_r("select send_order_id,uid,appid,unsubscribe_time,distribution_channel_id,created_at from force_subscribe_users where created_at > '{$start}' and created_at < '{$end}' limit $offset,$limit" . date("y-m-d H:i:s" . "\n"));
+                $users = DB::select("select send_order_id,uid,appid,unsubscribe_time,distribution_channel_id,created_at from force_subscribe_users where created_at > '{$start}' and created_at < '{$end}' limit $offset,$limit");
+                print_r("users_count:".count($users));
+                if (count($users) == 0) break;
+
+                foreach ($users as $user) {
+                    $is_unsub_in_one_day = false;
+                    $is_pay_in_one_day = false;
+                    $is_pay_in_two_days = false;
+                    $is_pay_in_three_days = false;
+                    $is_unsub_in_two_days = false;
+                    $is_unsub_in_three_days = false;
+                    $is_unsub_in_three_month = false;
+
+                    $order_sum_in_one_day = 0;
+                    $order_sum_in_two_day = 0;
+                    $order_sum_in_three_day = 0;
+                    $order_sum_in_one_month = 0;
+                    $order_sum_in_two_month = 0;
+                    $order_sum_in_three_month = 0;
+
+                    $order = DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->first();
+                    if ($order) {
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400)//24小时内
+                        {
+                            @$data[$user->appid]['pay_user_num_in_one_day']++;
+                            $is_pay_in_one_day = true;
+                        }
+
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400 * 2)//48小时内
+                        {
+                            $is_pay_in_two_days = true;
+                        }
+
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400 * 3)//72小时内
+                        {
+                            @$data[$user->appid]['pay_user_num_in_three_days']++;
+                            $is_pay_in_three_days = true;
+                        }
+
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400 * 30)//30天内
+                        {
+                            @$data[$user->appid]['pay_user_num_in_one_month']++;
+                        }
+
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400 * 60)//60天内
+                        {
+                            @$data[$user->appid]['pay_user_num_in_two_month']++;
+                        }
+
+                        if (strtotime($order->created_at) < strtotime($user->created_at) + 86400 * 90)//90天内
+                        {
+                            @$data[$user->appid]['pay_user_num_in_three_month']++;
+                        }
+
+                        $order_sum_in_one_day = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400))->sum('price');
+                        //$order_sum_in_two_day = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400*2))->sum('price');
+                        $order_sum_in_three_day = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400*3))->sum('price');
+                        $order_sum_in_one_month = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400*30))->sum('price');
+                        $order_sum_in_two_month = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400*60))->sum('price');
+                        $order_sum_in_three_month = (float)DB::table('orders')->where('uid', $user->uid)->where('status', 'PAID')->where('created_at','<=',date('Y-m-d H:i:s',strtotime($user->created_at)+86400*90))->sum('price');
+
+
+                    }
+                    @$data[$user->appid]['order_sum_in_one_day'] += $order_sum_in_one_day;
+                    @$data[$user->appid]['order_sum_in_three_day'] += $order_sum_in_three_day;
+                    @$data[$user->appid]['order_sum_in_one_month'] += $order_sum_in_one_month;
+                    @$data[$user->appid]['order_sum_in_two_month'] += $order_sum_in_two_month;
+                    @$data[$user->appid]['order_sum_in_three_month'] += $order_sum_in_three_month;
+
+                    @$data[$user->appid]['fans_num']++;
+
+                    if ($user->unsubscribe_time && strtotime($user->unsubscribe_time) < strtotime($user->created_at) + 86400*30)//30天内取注
+                    {
+                        @$data[$user->appid]['unsub_user_num_in_one_month']++;
+                    }
+
+                    if ($user->unsubscribe_time && strtotime($user->unsubscribe_time) < strtotime($user->created_at) + 86400*60)//60天内取注
+                    {
+                        @$data[$user->appid]['unsub_user_num_in_two_month']++;
+                    }
+
+                    if ($user->unsubscribe_time && strtotime($user->unsubscribe_time) < strtotime($user->created_at) + 86400*90)//90天内取注
+                    {
+                        @$data[$user->appid]['unsub_user_num_in_three_month']++;
+                    }
+
+                }
+
+                $offset = $offset + $limit;
+
+            }
+
+            foreach ($data as $appid => $item) {
+                $_data = [];
+                $_data['appid'] = $appid;
+                $_data['date'] = $date;
+                $_data['fans_num'] = isset($item['fans_num']) ? $item['fans_num'] : 0;
+                $_data['order_sum_in_one_day'] = $item['order_sum_in_one_day'];//24小时充值收益
+                $_data['order_sum_in_three_day'] = $item['order_sum_in_three_day'];//72小时充值
+
+                //30天数据
+                $_data['unsub_user_num_in_one_month'] = isset($item['unsub_user_num_in_one_month']) ? $item['unsub_user_num_in_one_month'] : 0;//30天内取关粉丝数
+                $_data['order_sum_in_one_month'] = $item['order_sum_in_one_month'];//30天充值
+
+                //60天数据
+                $_data['unsub_user_num_in_two_month'] = isset($item['unsub_user_num_in_two_month']) ? $item['unsub_user_num_in_two_month'] : 0;//60天取关粉丝数
+                $_data['pay_user_num_in_two_month'] = isset($item['pay_user_num_in_two_month']) ? $item['pay_user_num_in_two_month'] : 0;//60天内首充用户数
+                $_data['order_sum_in_two_month'] = $item['order_sum_in_two_month'];//60天充值
+
+                //90天数据
+                $_data['unsub_user_num_in_three_month'] = isset($item['unsub_user_num_in_three_month']) ? $item['unsub_user_num_in_three_month'] : 0;//90天取关粉丝数
+                $_data['order_sum_in_three_month'] = $item['order_sum_in_three_month'];//90天充值
+                $_data['pay_user_num_in_three_month'] = isset($item['pay_user_num_in_three_month']) ? $item['pay_user_num_in_three_month'] : 0;//90天内首充用户数
+
+                $_data['created_at'] = $_data['updated_at'] = date('Y-m-d H:i:s');
+                $_m_data[] = $_data;
+            }
+            DB::table('sub_user_recharge_stat')->insert($_m_data);
+
+            Log::info("======强关粉丝充值统计生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+            print_r("======强关粉丝充值统计生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+
+
+        }
+    }
+}

+ 47 - 0
app/Console/Commands/PaidUserRemind.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class PaidUserRemind extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'PaidUserRemind';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'PaidUserRemind';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+    public function start(){
+        CustomMsgService::add_template_pay_push_daily();
+
+    }
+}

+ 85 - 0
app/Console/Commands/PaymentQueryTask.php

@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/12/21
+ * Time: 下午2:12
+ */
+
+namespace App\Console\Commands;
+
+use App\Libs\Pay\SandPay;
+use App\Libs\PayHelper;
+use App\Modules\Finance\Models\WithdrawCash;
+use App\Modules\Finance\Services\AdvancedPaymentService;
+use App\Modules\Finance\Services\BatchPaymentService;
+use App\Modules\Finance\Services\LiquidatedStatService;
+use App\Modules\Finance\Services\PaymentService;
+use App\Modules\Finance\Services\WithdrawCashService;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+class PaymentQueryTask extends Command
+{
+
+    /**
+     * 执行命令   php artisan payment_query_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'payment_query_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '支付通道打款结果查询';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        print_r("======支付通道打款结果查询 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======支付通道打款结果查询 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        $this->BatchPaymentQuery();
+     
+        Log::info("======支付通道余额结果查询 【任务执行结束】=====[" . date("y-m-d H:i:s" . "\n"));
+        print_r("======支付通道余额结果查询 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+    }
+
+
+    private function BatchPaymentQuery()
+    {
+        $pay_service = new SandPay;
+        $payment_service = new AdvancedPaymentService;
+        $payments = $payment_service->findPayingBatchPayments();
+        foreach ($payments as $pay) {
+            $result = $pay_service->queryOrder([
+                'order_no'  => $pay->trade_no,
+                'pay_time' => $pay->pay_time,
+            ], $pay->is_company == 0);
+            if ($result['result'] == 'success') {
+                print_r(($pay->id) . '---执行---start---' . "\n");
+                $sand_serial = $result['content']->sandSerial;
+                $payment_service->updateBatchPaymentStatus($pay, AdvancedPaymentService::auto_success, 0, $result, $sand_serial);
+                print_r(($pay->id) . '---执行---end---' . "\n");
+            } else if ($result['result'] == 'failure') {
+                $payment_service->updateBatchPaymentStatus($pay, AdvancedPaymentService::auto_failure, 0, $result);
+            } else {
+                $pay->pay_merchant_source_msg = json_encode($result);
+                $pay->pay_merchant_source_result = '正在处理中';
+                $pay->save();
+            }
+        }
+    }
+}

+ 62 - 0
app/Console/Commands/PaymentStatisticTask.php

@@ -0,0 +1,62 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: tandunzhao
+ * Date: 2017/12/5
+ * Time: 下午4:24
+ */
+
+namespace App\Console\Commands;
+
+use App\Modules\Channel\Services\ChannelService;
+use App\Modules\Finance\Services\FinanceService;
+use Log;
+use Illuminate\Console\Command;
+
+class PaymentStatisticTask extends Command
+{
+    /**
+     * 执行命令   php artisan payment_statistic_task
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'payment_statistic_task';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日打款报表生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        print_r("======每日打款报表生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======每日打款报表生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        $channels = $this->getAllChannel();
+        foreach ($channels as $channel) {
+            //print_r($channel->id."=".$channel->name."\n");
+            $channelId = $channel->id;
+            FinanceService::makeYesterdayWithdrawCashStatistics($channelId);
+//            print_r($channelId."=".$channelName."=".$rechargeAmount."\n");
+        }
+        Log::info("======每日打款报表生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======每日打款报表生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+    }
+
+    /**
+     * 获取所有渠道
+     * @return mixed
+     */
+    public function getAllChannel() {
+        $channels = ChannelService::getAllChannels();
+        return $channels;
+    }
+}

+ 51 - 0
app/Console/Commands/ProductStats/DailyProductionStats.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\ProductionStatsEmailService;
+
+use Illuminate\Console\Command;
+use DB;
+
+class DailyProductionStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'saveDailyProductsStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '保存每日作品分析数据';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $from_date = date('Y-m-d 00:00:00',strtotime('-1 day'));
+        $end_date = date('Y-m-d 23:59:59',strtotime('-1 day'));
+        //更新男女频
+        DB::update("UPDATE book_updates a  JOIN books b on a.bid=b.id JOIN book_categories c on b.category_id=c.id  set a.channel_name=c.channel_name  WHERE a.update_date= DATE_ADD(date(NOW()),INTERVAL -1 DAY)");
+        //ProductionStatsEmailService::setDayStats($from_date,$end_date);
+        ProductionStatsEmailService::setDayStatsNew($from_date,$end_date);
+    }
+}

+ 49 - 0
app/Console/Commands/ProductStats/MonthlyProductionStats.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\ProductionStatsEmailService;
+
+use Illuminate\Console\Command;
+
+class MonthlyProductionStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'saveMonthlyProductsStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送每日作品分析报表';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $from_date = date('Y-m-01 00:00:00',strtotime('-1 month'));
+        $end_date = date('Y-m-d 23:59:59',strtotime(date('Y-m-01').' -1 day'));
+
+        ProductionStatsEmailService::setMonthStats($from_date,$end_date);
+
+    }
+}

+ 116 - 0
app/Console/Commands/ProductStats/SendDailyNewProductionStats.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\ProductionStatsEmailService;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use DB;
+use App\Modules\Message\MessageNotify;
+class SendDailyNewProductionStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SendDailyNewProductsStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送每日新增作品';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $date = date('Y-m-d',strtotime('-1 day'));
+       // $date = date('Y-m-d',strtotime('-3 day'));
+        $new_products = DB::select("SELECT books.id,books.name,book_configs.is_on_shelf,book_categories.pid FROM book_updates
+ JOIN books ON books.id=book_updates.bid JOIN book_configs ON book_configs.bid=books.id
+  LEFT JOIN book_categories ON book_categories.id=books.category_id
+  WHERE book_updates.update_date='{$date}'
+ AND book_configs.is_on_shelf IN (1,2) AND (book_updates.update_type='add_book' OR (book_updates.update_type='onshelfstatus'
+  AND book_updates.update_chapter_count=0 AND update_words IN (1,2))) group by book_updates.bid");
+
+        //$suspends = ProductionStatsEmailService::getSuspendProducts(false);
+        $stats=array(
+            ['total'=>0,'internal'=>0,'date'=>$date],
+            ['total'=>0,'internal'=>0,'date'=>$date],
+            ['total'=>0,'internal'=>0,'date'=>$date]
+        );
+        $book_list = array();
+        foreach ($new_products as $product){
+            $stats[0]['total'] = $stats[0]['total'] + 1;
+            if($product->is_on_shelf == 1) {
+                $stats[0]['internal']++;
+            }
+            if(isset($product->pid) && $product->pid==1) {
+                $stats[1]['total'] = $stats[1]['total'] + 1;
+                if($product->is_on_shelf == 1) {
+                    $stats[1]['internal']++;
+                }
+            }
+            if(isset($product->pid) && $product->pid==2) {
+                $stats[2]['total'] = $stats[2]['total'] + 1;
+                if($product->is_on_shelf == 1) {
+                    $stats[2]['internal']++;
+                }
+            }
+            $gender ='';
+            switch ($product->pid){
+                case 1:$gender='男频';break;
+                case 2:$gender='女频';break;
+                default :$gender='未知';
+            }
+            $book_list[] = array($product->id,$product->name,$gender,($product->is_on_shelf==1)?'内部上架':'外部上架');
+        }
+        $books_header = ['bid','书名','一级分类','作品类型'];
+        $storage_file = 'app/new_books'.date('Y-m-d').'.xlsx';
+        saveExcelData($books_header ,$book_list,storage_path($storage_file));
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $page = view('email.newProductsStats',['data'=>$stats,'datas2'=>$book_list,'title'=>$date.' 作品数据报表','title2'=>$date.' 新增作品']);
+        $html = response($page)->getContent();
+
+        $to_users = '';
+        foreach ($to_user as $item){
+            $to_users .= $item['address'].";";
+        }
+
+
+        $notify = MessageNotify::mail([
+            'to_emails' => $to_users,
+            'subject' => '网读云'."新增作品统计",
+            'body' => $html,
+            'delay_times' => 0,
+        ]);
+        $notify->addAttach($storage_file);
+        $notify->notify();
+
+        //SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>'追书云'."新增作品统计",'body'=>$html],storage_path('app/new_books'.date('Y-m-d').'.xlsx'));
+
+    }
+}

+ 98 - 0
app/Console/Commands/ProductStats/SendDailyProductionStats.php

@@ -0,0 +1,98 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\ProductionStatsEmailService;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use DB;
+use App\Modules\Message\MessageNotify;
+class SendDailyProductionStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SendDailyProductsStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送每日作品分析数据';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $date = date('Y-m-d',strtotime('-1 day'));
+        $data = DB::table('product_stats')
+            ->where([['date','=',$date],['type','=','day']])
+            ->first();
+        if($data) {
+            $data = json_decode(json_encode($data),true);
+            $data['date'] = $date;
+        }else{
+            $data = ProductionStatsEmailService::getAll(date('Y-m-d 00:00:00',strtotime('-1 day')),date('Y-m-d 23:59:59',strtotime('-1 day')));
+            $data['date'] = $date;
+        }
+
+        $suspends = ProductionStatsEmailService::getSuspendProducts(false);
+        $suspends_format = array();
+        foreach ($suspends as $suspend){
+            $time_diff = time()-strtotime($suspend->updated_at);
+            $product_type = $suspend->is_on_shelf;
+            switch ($product_type){
+                case 1:$product_type = '内部作品';break;
+                case 2:$product_type = '外部作品';break;
+                default:;
+            }
+            $suspends_format[] = array($suspend->id,$suspend->name,$suspend->pid,$suspend->updated_at,round(($time_diff)/3600,1),round($time_diff/(3600*24),1),$product_type);
+        }
+        $suspends_header = ['bid','书名','一级分类','最近更新','累计断更时长(小时)','断更天数','作品类型'];
+        $storage_file = 'app/suspend_books'.date('Y-m-d').'.xlsx';
+        saveExcelData($suspends_header ,$suspends_format,storage_path($storage_file));
+        $to_user = array(
+                ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+                ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+                ['address'=>'zhoulj@iqiyoo.com','name'=>'周灵杰'],
+        );
+
+        $page = view('email.productStats',['data'=>$data,'datas2'=>$suspends_format,'title'=>$date.' 作品数据报表','title2'=>$date.' 断更作品']);
+        $html = response($page)->getContent();
+
+        $to_users = '';
+        foreach ($to_user as $item){
+            $to_users .= $item['address'].";";
+        }
+
+
+        $notify = MessageNotify::mail([
+            'to_emails' => $to_users,
+            'subject' => '网读云'.$date."断更作品数据报表",
+            'body' => $html,
+            'delay_times' => 0,
+        ]);
+        $notify->addAttach($storage_file);
+        $notify->notify();
+        //SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>'追书云'.$date."断更作品数据报表",'body'=>$html],storage_path('app/suspend_books'.date('Y-m-d').'.xlsx'));
+
+    }
+}

+ 76 - 0
app/Console/Commands/ProductStats/SendMonthStatsEmail.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+
+class SendMonthStatsEmail extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sendMonthOrderEmail';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送外部派单作品分析报表';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $lastMonthBegin = date('Y-m-01',strtotime('-1 month'));
+        $lastMonthEnd   = date('Y-m-d',strtotime(date('Y-m-01').' -1 day'));
+
+        $data = SendStatsEmailService::getOrderStats($lastMonthBegin,$lastMonthEnd);
+        //var_dump($data);
+        $data = json_decode(json_encode($data),true);
+        $page = view('email.monthStats',['datas'=>$data,'month'=>date('m月',strtotime('-1 month'))]);
+        $html = response($page)->getContent();
+        //\Log::info($html);
+        $data_temp = array();
+        foreach ($data as $key=>$value){
+            $data_temp[] = array(
+                $value['bid'],
+                $value['book_name'],
+                $value['order_num'],
+                $value['UV'],
+                $value['register_user_sum'],
+                $value['recharge_sum'],
+                $value['pid'],
+                $value['order_num']>0?round($value['register_user_sum']/$value['order_num'],2):0,
+                $value['order_num']>0?round($value['recharge_sum']/$value['order_num'],2):0,
+                $value['register_user_sum']>0?round($value['recharge_sum']/$value['register_user_sum'],2):0
+            );
+        }
+        $header = ['书籍ID','书籍名称','实际派单数','UV','注册用户数','充值','男女频','注册/派单','充值/派单','充值/注册'];
+        saveExcelData($header,$data_temp,storage_path('app/last_month_send_order.xlsx'));
+
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address'=>'zhoulj@iqiyoo.com','name'=>'周灵杰'],
+        );
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>'网读云'.date('m月',strtotime('-1 month'))."外部派单作品分析报表(修订)",'body'=>$html],storage_path('app/last_month_send_order.xlsx'));
+    }
+}

+ 68 - 0
app/Console/Commands/ProductStats/SendMonthlyProductStats.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace App\Console\Commands\ProductStats;
+
+use App\Modules\Statistic\Services\ProductionStatsEmailService;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use DB;
+
+class SendMonthlyProductStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SendMonthlyProductsStats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送每月作品分析数据';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $date = date('Y-m-01',strtotime('-1 month'));
+        $data = DB::table('product_stats')
+            ->where([['date','=',$date],['type','=','month']])
+            ->first();
+        if($data) {
+            $data = json_decode(json_encode($data),true);
+            $data['date'] = date('Y-m',strtotime('-1 month'));
+        }else{
+            $data = ProductionStatsEmailService::getAll(date('Y-m-01 00:00:00',strtotime('-1 month')),date('Y-m-d 23:59:59',strtotime(date('Y-m-01').'-1 day')));
+            $data['date'] = date('Y-m',strtotime('-1 month'));
+        }
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address'=>'zhoulj@iqiyoo.com','name'=>'周灵杰']
+        );
+
+        $page = view('email.productStats',['data'=>$data,'title'=>date('m月',strtotime('-1 month')).' 作品数据报表']);
+        $html = response($page)->getContent();
+
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>'网读云'.date('m月',strtotime('-1 month'))."作品数据报表",'body'=>$html]);
+
+    }
+}

+ 86 - 0
app/Console/Commands/ReadRecordPersistence.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use Redis;
+use DB;
+
+class ReadRecordPersistence extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'ReadRecordPersistence';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->saveDB();
+    }
+
+    private function saveDB(){
+        $result = $this->compactData();
+        if(!$result){
+            return ;
+        }
+        foreach ($result as $key=>$v){
+            $table = sprintf('record_records%s',$key);
+            DB::connection('read_record_mysql')->table($table)->insert($v);
+        }
+    }
+
+    private function getRecord(){
+        $length = Redis::Llen('ReadRecordStats');
+        if(!$length) return [];
+        $count = ceil($length/200);
+        $result = [];
+        for ($i=0;$i <$count;$i++){
+            $start = $i*200;
+            $end = $start+199;
+            $result[] = Redis::Lrange('ReadRecordStats',$start,$end);
+        }
+        Redis::del('ReadRecordStats');
+        return $result;
+    }
+
+    private function compactData(){
+        $data = $this->getRecord();
+        if(!$data){
+            return [];
+        }
+        $result = [];
+        foreach ($data as $item){
+            foreach ($item  as $v){
+                $record = json_decode($v,1);
+                $table = $record['uid']%2048;
+                $result[$table][] =  $record;
+            }
+        }
+
+        return  $result;
+    }
+}

+ 47 - 0
app/Console/Commands/RecoverPush.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class RecoverPush extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'recoverpush';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->recoverActivity();
+    }
+
+    public function recoverActivity(){
+        CustomMsgService::add_news_recovery_push_hot();
+        CustomMsgService::add_news_recovery_push_activity();
+    }
+}

+ 76 - 0
app/Console/Commands/RepeatBookOrderRecover.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+class RepeatBookOrderRecover extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:bor {--type=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '单本订购重复订单恢复';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $options = $this->option('type');
+        if($options){
+            echo $this->stats();
+        }else{
+            echo $this->start();
+        }
+        return;
+    }
+
+    public function  start(){
+        $sql = "SELECT uid,bid,COUNT(*) FROM book_orders where uid>0 and bid>0 GROUP BY uid,bid HAVING COUNT(*) >=2";
+        $res = DB::select($sql);
+        $i = 0;
+        foreach ($res as $v){
+            $order = DB::table('book_orders')->where('bid',$v->bid)->where('uid',$v->uid)->first();
+            $update_user_sql = "UPDATE users set balance = balance+{$order->fee},reward_balance=reward_balance+{$order->reward_balance},charge_balance=charge_balance+{$order->charge_balance} where id = {$order->uid}";
+            DB::update($update_user_sql);
+            DB::table('book_orders')->where('id',$order->id)->update(['uid'=>-$order->uid]);
+            $i++;
+        }
+        return '修改了'.$i.'个用户';
+    }
+
+    public function stats(){
+        $sql = "SELECT  id,bid,fee,date(created_at) as days,send_order_id,charge_balance,reward_balance FROM book_orders WHERE uid<0 and fee >0";
+        $res = DB::select($sql);
+        $i = 0;
+        foreach ($res as $v){
+            $update_sql = "update book_order_statistical set fee=fee-{$v->fee}, reward_balance=reward_balance-{$v->reward_balance}, charge_balance=charge_balance-{$v->charge_balance} where bid={$v->bid} and `day`='{$v->days}'";
+            DB::update($update_sql);
+            DB::table('book_orders')->where('id',$v->id)->update(['fee'=>0]);
+            //DB::table('book_order_statistical')->where('bid',$v->bid)->where('day',$v->days)->
+            $i++;
+        }
+        return '修改了'.$i.'个记录';
+    }
+}

+ 80 - 0
app/Console/Commands/SendOrder/GenerateBookUvRegisterStat.php

@@ -0,0 +1,80 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: sogndb
+ * Date: 2018/02/05
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use DB;
+use Illuminate\Console\Command;
+use Log;
+
+class GenerateBookUvRegisterStat extends Command
+{
+    /**
+     * 执行命令   php artisan send_order:generate_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sendOrder_book_uv_register_stat';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '内外部派单按书累计数据';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $date_end = date("Y-m-d");
+        $date_begin = date("Y-m-d", strtotime(' -1 day'));
+
+
+        $base_sql = "SELECT book_name,bid,sum(uv) as total_uv, sum(register_user_num) total_register_user_num 
+        FROM send_orders_stats WHERE send_time BETWEEN '%s' AND '%s'";
+        //内部
+        $inside_sql = $base_sql . "AND force_user_num<20 GROUP BY bid ORDER BY total_uv desc LIMIT 10";
+        $inside_result = DB::select(sprintf($inside_sql, $date_begin, $date_end));
+
+        //外部
+        $outside_sql = $base_sql . "AND force_user_num>=20  GROUP BY bid ORDER BY total_register_user_num desc LIMIT 10";
+        $outside_result = DB::select(sprintf($outside_sql, $date_begin, $date_end));
+
+        $to_user = array(
+            ['address' => 'songdb@iqiyoo.com', 'name' => 'songdb'],
+            ['address' => 'zhaojp@yqsd.net', 'name' => '赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $content ='';
+        if ($inside_result) {
+            $content .= "<table border='1' cellpadding='10' cellspacing='0'><tr><td align='center'>类型</td><td align='center'>书本id</td><td align='center'>书名</td><td align='center'>总UV</td><td align='center'>总注册用户数</td></tr>";
+            foreach ($inside_result as $item) {
+                $content .= "<tr><td align='center'>内部派单</td><td align='center'>{$item->bid}</td><td align='center'>{$item->book_name}</td><td align='center'>{$item->total_uv}</td><td align='center'>{$item->total_register_user_num}</td></tr>";
+            }
+            $content .= "</table>";
+        }
+
+        $content.='</hr>';
+        if ($outside_result) {
+            $content .= "<table border='1' cellpadding='10' cellspacing='0'><tr><td align='center'>类型</td><td align='center'>书本id</td><td align='center'>书名</td><td align='center'>总UV</td><td align='center'>总注册用户数</td></tr>";
+            foreach ($outside_result as $item) {
+                $content .= "<tr><td align='center'>外部派单</td><td align='center'>{$item->bid}</td><td align='center'>{$item->book_name}</td><td align='center'>{$item->total_uv}</td><td align='center'>{$item->total_register_user_num}</td></tr>";
+            }
+            $content .= "</table>";
+        }
+        SendStatsEmailService::SendHtmlEmailWithAcce($to_user, ['subject' => '网读云'.date("Y-m-d", time()) . "内外部派单按书统计数据", 'body' => $content]);
+    }
+}

+ 68 - 0
app/Console/Commands/SendOrder/GenerateDayByBooksStat.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: sogndb
+ * Date: 2018/02/05
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use App\Modules\SendOrder\Models\SendOrderForceDayStat;
+use App\Modules\SendOrder\Services\SendOrderForceDayStatService;
+use App\Modules\SendOrder\Services\SendOrderStatService;
+use Illuminate\Console\Command;
+use Log;
+use DB;
+
+class GenerateDayByBooksStat extends Command
+{
+    /**
+     * 执行命令   php artisan send_order_generate_force_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'send_order:generate_stats_by_bid';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日图书派单数据生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+
+        $i=1;
+        $date = date("Y-m-d", strtotime(' -'.$i.' day'));
+
+        $data = SendOrderForceDayStatService::getSendOrdersDayStatsByBid($date);
+        $to_insert = json_decode(json_encode($data),true);
+        \DB::table('book_promotion_day_stats')->insert($to_insert);
+        $end_order_stats = \DB::table('send_orders_force_day_stats')
+            ->join('books','send_orders_force_day_stats.bid','=','books.id')
+            ->join('book_categories','book_categories.id','=','books.category_id')
+            ->where('send_orders_force_day_stats.date',$date)
+            ->select([DB::raw('sum(send_orders_force_day_stats.recharge_amount) as total_recharge'),'pid'])
+            ->groupBy('book_categories.pid')
+            ->get();
+        $male_recharge=$female_recharge=0;
+        foreach ($end_order_stats as $end_order_stat){
+            if($end_order_stat->pid==1) $male_recharge = $end_order_stat->total_recharge;
+            if($end_order_stat->pid==2) $female_recharge = $end_order_stat->total_recharge;
+        }
+        $insert_data = compact('male_recharge','female_recharge');
+        $insert_data['date'] = $date;
+        $insert_data['created_at']=date('Y-m-d H:i:s');
+        $insert_data['updated_at']=date('Y-m-d H:i:s');
+        DB::table('order_gender_stats')->insert($insert_data);
+    }
+}

+ 115 - 0
app/Console/Commands/SendOrder/GenerateForceDayStat.php

@@ -0,0 +1,115 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: sogndb
+ * Date: 2018/02/05
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use App\Modules\SendOrder\Services\SendOrderForceDayStatService;
+use App\Modules\SendOrder\Services\SendOrderService;
+use Illuminate\Console\Command;
+use Log;
+use DB;
+
+class GenerateForceDayStat extends Command
+{
+    /**
+     * 执行命令   php artisan send_order_generate_force_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'send_order:generate_force_day_stat';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日图书派单数据生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        ini_set('memory_limit', '1280M');
+        print_r("======每日图书派单数据生成 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======每日图书派单数据生成 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        $date = date("Y-m-d", strtotime(' -1 day'));
+        try{
+            SendOrderForceDayStatService::generateForceDayStat($date);
+        }catch (\Exception $e){
+            Log::info("======每日图书派单数据生成 =====".$e . date("y-m-d H:i:s" . "\n"));
+        };
+
+
+        Log::info("======每日图书派单数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======每日图书派单数据生成 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+
+        $i=1;
+        $date = date("Y-m-d", strtotime(' -' . $i . ' day'));
+
+        print_r("======每日男女频充值数据 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======每日男女频充值数据 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        //开始生成男女频充值数据
+        $end_order_stats = DB::table('send_orders_force_day_stats')
+            ->join('books','send_orders_force_day_stats.bid','=','books.id')
+            ->join('book_categories','book_categories.id','=','books.category_id')
+            ->where('send_orders_force_day_stats.date',$date)
+            ->select([DB::raw('sum(send_orders_force_day_stats.recharge_amount) as total_recharge'),'pid'])
+            ->groupBy('book_categories.pid')
+            ->get();
+        $male_recharge=$female_recharge=0;
+        foreach ($end_order_stats as $end_order_stat){
+            if($end_order_stat->pid==1) $male_recharge = $end_order_stat->total_recharge;
+            if($end_order_stat->pid==2) $female_recharge = $end_order_stat->total_recharge;
+        }
+        $insert_data = compact('male_recharge','female_recharge');
+        $insert_data['date'] = $date;
+        $insert_data['month'] = date('Y-m',strtotime(' -'.$i.' day'));
+        $insert_data['created_at']=date('Y-m-d H:i:s');
+        $insert_data['updated_at']=date('Y-m-d H:i:s');
+        DB::table('order_gender_stats')->insert($insert_data);
+
+        Log::info("======每日男女频充值数据 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======每日男女频充值数据 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+
+
+        print_r("======书籍数据每日统计 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+        Log::info("======书籍数据每日统计 【任务执行开始】=====" . date("y-m-d H:i:s" . "\n"));
+
+        $data = SendOrderForceDayStatService::getSendOrdersDayStatsByBid($date);
+
+        $end_date = date('Y-m-d', strtotime($date) + 86400);
+        $send_num_data = SendOrderService::getBookdSendNum($date, $end_date);
+
+        $to_insert = json_decode(json_encode($data), true);
+        $once_data = [];
+        $once_num = 500;
+        foreach ($to_insert as $_item) {
+            $real_send_order_num = isset($send_num_data[$_item['bid']]) ? $send_num_data[$_item['bid']] : 0;
+            $_item['real_send_order_num'] = $real_send_order_num;
+
+            $once_data[] = $_item;
+
+            if (count($once_data) >= $once_num) {
+                DB::table('book_promotion_day_stats')->insert($once_data);
+                $once_data = [];
+            }
+        }
+        $once_data && DB::table('book_promotion_day_stats')->insert($once_data);
+
+        Log::info("======书籍数据每日统计 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+        print_r("======书籍数据每日统计 【任务执行结束】=====" . date("y-m-d H:i:s" . "\n"));
+
+    }
+}

+ 51 - 0
app/Console/Commands/SendOrder/GenerateStat.php

@@ -0,0 +1,51 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: sogndb
+ * Date: 2018/02/05
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use App\Modules\SendOrder\Services\SendOrderStatService;
+use Log;
+use Illuminate\Console\Command;
+
+class GenerateStat extends Command
+{
+    /**
+     * 执行命令   php artisan send_order:generate_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'send_order:generate_stat';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '派单统计数据生成';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        ini_set('memory_limit', '1024M');
+        print_r('memory_used:'.memory_get_usage()."\n");
+        print_r("======派单统计数据生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======派单统计数据生成 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        //SendOrderStatService::generateStat();
+        SendOrderStatService::generateStatsByChunk();
+        Log::info("======派单统计数据生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======派单统计数据生成 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r('memory_used:'.memory_get_usage()."\n");
+    }
+}

+ 205 - 0
app/Console/Commands/SendOrder/GenerateUserRegistStat.php

@@ -0,0 +1,205 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Hardy
+ * Date: 2020/7/31
+ * Time: 21:37
+ */
+
+
+namespace App\Console\Commands\SendOrder;
+
+
+use App\Modules\Order\Services\OrderService;
+use App\Modules\SendOrder\Models\SendOrderByRegist;
+use App\Modules\SendOrder\Services\SendOrderByRegistService;
+use Illuminate\Console\Command;
+
+class GenerateUserRegistStat extends Command
+{
+    /**
+     * The name and signature of the console command.
+     * php artisan GenerateUserRegistStat
+     * @var string
+     */
+    protected $signature = 'GenerateUserRegistStat {--begin_date=} {--end_date=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '每日生成派单数据';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+
+    public function start()
+    {
+        $begin_date = $this->option('begin_date');
+        $end_date   = $this->option('end_date');
+
+        if(!isset($begin_date))
+        {
+            $begin_date=date('Y-m-d', strtotime('-1 day',strtotime(now())));
+            $end_date =date('Y-m-d', strtotime(now()));
+        }
+
+
+        myLog('SendOrderByRegist')->notice('【' . $begin_date . '->' . $end_date . '】-------  开始');
+
+        $endTime = $end_date;
+
+        $runDay = $begin_date;
+
+        while (strtotime($runDay) < strtotime($endTime)) {
+            var_dump($runDay);
+            $this->processOneDayNew($runDay);
+            $runDay = date('Y-m-d', strtotime('+1 day', strtotime($runDay)));
+        }
+        myLog('SendOrderByRegist')->notice('【' . $begin_date . '->' . $end_date . '】-------  结束');
+    }
+
+    public function processOneDayNew($day)
+    {
+        //清理当天的派单按日注册
+        myLog('SendOrderByRegist')->notice($day . '-------  开始:');
+        $startTime = date('Y-m-d', strtotime($day));
+        $endTime   = date('Y-m-d', strtotime('+1 day', strtotime($startTime)));
+
+        //查询派单
+        $orderService = new SendOrderByRegistService();
+
+        $sendOrderIDs = $orderService->getSendOrderIdFromOrigin($startTime, $endTime);
+
+        //dd(collect($sendOrderIDs)->implode('send_order_id', ', '));
+
+        $bitch =500;
+        $partIds = [];
+        for ($i = 1; $i <= count($sendOrderIDs); $i++) {
+            $partIds[] = $sendOrderIDs[$i - 1]->send_order_id;
+
+            if ($i > 1 && $i % $bitch == 0) {
+                $orderService->deleteRecs($partIds);
+                $partIds = [];
+            }
+        }
+        if(count($partIds)>0)
+        {
+            $orderService->deleteRecs($partIds);
+        }
+        myLog('SendOrderByRegist')->notice($day . '-------  清理历史记录完成');
+
+
+        myLog('SendOrderByRegist')->notice('有效派单数'.count($sendOrderIDs));
+        foreach ($sendOrderIDs as $item) {
+            myLog('SendOrderByRegist')->notice('当前派单ID'.$item->send_order_id);
+            self:: processSendOrderById($item->send_order_id, $endTime);
+        }
+        myLog('SendOrderByRegist')->notice($day . '-------  结束');
+
+    }
+
+
+    /**
+     * @param int $send_order_id
+     * @param string $endTime 不包含
+     */
+    public function processSendOrderById($send_order_id, $endTime)
+    {
+        $modelList['send_order_id'] = $send_order_id;
+        //查询首充数及首充金额
+        $orderService                  = new OrderService();
+        $find                          = $orderService->getSendOrderFirstPayCountAndPriceByID($send_order_id, $endTime);
+        $modelList['first_pay_count']  = empty($find) ? 0 : $find['first'];
+        $modelList['first_pay_amount'] = empty($find) ? 0 : $find['price'];
+
+        //付费人数,付费次数和充值总额
+        $find                             = $orderService->getSendOrderSuccessPayCountByID($send_order_id, $endTime);
+        $modelList['success_user_count']  = empty($find) ? 0 : $find['u_num'];
+        $modelList['success_order_count'] = empty($find) ? 0 : $find['num'];
+        $modelList['total_amount']        = empty($find) ? 0 : $find['price'];
+
+        //24小时充值充值金额
+        $hour                 = 24;
+        $find                 = $orderService->getSendOrderPayPriceByIdAndHour($send_order_id, $endTime, $hour);
+        $modelList['hour_24'] = empty($find) ? 0 : $find['price'];
+
+        //24小时首充用户数
+        $find                             = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 1);
+        $modelList['hour_24_first_count'] = empty($find) ? 0 : $find['num'];
+        //24小时非首充用户数
+        $find                                 = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 0);
+        $modelList['hour_24_not_first_count'] = empty($find) ? 0 : $find['num'];
+
+
+        //3天充值充值金额
+        $hour               = 24 * 3;
+        $find               = $orderService->getSendOrderPayPriceByIdAndHour($send_order_id, $endTime, $hour);
+        $modelList['day_3'] = empty($find) ? 0 : $find['price'];
+
+        //3天首充用户数
+        $find                           = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 1);
+        $modelList['day_3_first_count'] = empty($find) ? 0 : $find['num'];
+        //3天非首充用户数
+        $find                               = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 0);
+        $modelList['day_3_not_first_count'] = empty($find) ? 0 : $find['num'];
+
+        //7天充值充值金额
+        $hour               = 24 * 7;
+        $find               = $orderService->getSendOrderPayPriceByIdAndHour($send_order_id, $endTime, $hour);
+        $modelList['day_7'] = empty($find) ? 0 : $find['price'];
+
+        //7天首充用户数
+        $find                           = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 1);
+        $modelList['day_7_first_count'] = empty($find) ? 0 : $find['num'];
+        //7天非首充用户数
+        $find                               = $orderService->getSendOrderPayUserCountByIdAndHour($send_order_id, $endTime, $hour, 0);
+        $modelList['day_7_not_first_count'] = empty($find) ? 0 : $find['num'];
+
+        myLog('SendOrderByRegist')->notice('【' . $send_order_id . '】-------  开始保存数据');
+
+        $helper = new SendOrderByRegistService();
+        $find   = $helper->search(['send_order_id' => $send_order_id], true)->first();
+
+        if (!empty($find)) {
+            $find->first_pay_count         += $modelList['first_pay_count'];
+            $find->first_pay_amount        += $modelList['first_pay_amount'];
+            $find->success_user_count      += $modelList['success_user_count'];
+            $find->success_order_count     += $modelList['success_order_count'];
+            $find->total_amount            += $modelList['total_amount'];
+            $find->hour_24                 += $modelList['hour_24'];
+            $find->hour_24_first_count     += $modelList['hour_24_first_count'];
+            $find->hour_24_not_first_count += $modelList['hour_24_not_first_count'];
+            $find->day_3                   += $modelList['day_3'];
+            $find->day_3_first_count       += $modelList['day_3_first_count'];
+            $find->day_3_not_first_count   += $modelList['day_3_not_first_count'];
+            $find->day_7                   += $modelList['day_7'];
+            $find->day_7_first_count       += $modelList['day_7_first_count'];
+            $find->day_7_not_first_count   += $modelList['day_7_not_first_count'];
+            $find->save();
+        } else {
+            SendOrderByRegist::insert($modelList);
+        }
+
+        myLog('SendOrderByRegist')->notice('【' . $send_order_id . '】-------  保存数据完成');
+    }
+}

+ 156 - 0
app/Console/Commands/SendOrder/SendOrderSendOrderPvUv.php

@@ -0,0 +1,156 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: z-yang
+ * Date: 2020/4/10
+ * Time: 11:52
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use DB;
+use Illuminate\Console\Command;
+use Log;
+use Redis;
+
+class SendOrderSendOrderPvUv extends Command
+{
+    /**
+     * 执行命令   php artisan send_order:generate_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SendOrder:SendOrderSendOrderPvUv {--type=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '派单即时访问量';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+
+    public function handle(){
+        $type = $this->option('type');
+        if($type == 'history'){
+            $this->updateHistotyStats();
+        }else{
+            $this->updateTodayStats();
+        }
+    }
+
+    private function updateTodayStats(){
+        $day = date('Y-m-d');
+        $i = 0;
+        $send_order_list = Redis::SMEMBERS('send_order' . $day);
+        //while (true){
+            /*$list = Redis::sscan('send_order' . $day,$i,['match'=>'*','count'=>100]);
+            if(!$list){
+                break;
+            }
+            list($i,$send_order_list) = $list;*/
+            foreach ($send_order_list as $send_order_id){
+                $uv = (int)(Redis::hget('send_order_uv_'.$send_order_id,$day));
+                $pv = (int)(Redis::hget('send_order_pv_'.$send_order_id,$day));
+                $pvInfo = DB::table('send_order_uv_pv')->where('send_order_id',$send_order_id)->select('history_pv','history_uv','total_pv','total_uv','uv_reach_200_time','uv_reach_500_time')->first();
+                if($pvInfo){
+                    $total_uv = $pvInfo->history_uv+$uv;
+                    $total_pv = $pvInfo->history_pv+$pv;
+                    $update_data = [
+                        'today_pv'=>$pv,
+                        'today_uv'=>$uv,
+                        'total_pv'=>$total_pv,
+                        'total_uv'=>$total_uv,
+                        'updated_at'=>date('Y-m-d H:i:s')
+                    ];
+
+                    if(!$pvInfo->uv_reach_200_time  && ($total_uv-200) > 0){
+                        $update_data['uv_reach_200_time'] = date('Y-m-d H:i:s');
+                    }
+                    if(!$pvInfo->uv_reach_200_time && $pvInfo->total_uv < 200 && $total_uv>200){
+                        $update_data['uv_reach_200_time'] = date('Y-m-d H:i:s');
+                    }
+                    if(!$pvInfo->uv_reach_500_time && ($total_uv-500) > 0){
+                        $update_data['uv_reach_500_time'] = date('Y-m-d H:i:s');
+                    }
+                    if(!$pvInfo->uv_reach_500_time && $pvInfo->total_uv < 500 && $total_uv>500){
+                        $update_data['uv_reach_500_time'] = date('Y-m-d H:i:s');
+                    }
+                    DB::table('send_order_uv_pv')->where('send_order_id',$send_order_id)->update($update_data);
+                }else{
+                    $insert_data = [
+                        'today_pv'=>$pv,
+                        'today_uv'=>$uv,
+                        'total_pv'=>$pv,
+                        'total_uv'=>$uv,
+                        'history_pv'=>0,
+                        'history_uv'=>0,
+                        'send_order_id'=>$send_order_id,
+                        'created_at'=>date('Y-m-d H:i:s'),
+                        'updated_at'=>date('Y-m-d H:i:s')
+                    ];
+                    if(($uv-200) > 0){
+                        $insert_data['uv_reach_200_time'] = date('Y-m-d H:i:s');
+                    }
+                    if(($uv-500) > 0){
+                        $insert_data['uv_reach_500_time'] = date('Y-m-d H:i:s');
+                    }
+                    DB::table('send_order_uv_pv')->insert($insert_data);
+                }
+            }
+        //}
+    }
+    private function updateHistotyStats(){
+        $day = date('Y-m-d',time()-86400);
+        $i = 0;
+        $send_order_list = Redis::SMEMBERS('send_order' . $day);
+        //while (true){
+            /*$list = Redis::sscan('send_order' . $day,$i,['match'=>'*','count'=>100]);
+            if(!$list){
+                break;
+            }
+            list($i,$send_order_list) = $list;*/
+            foreach ($send_order_list as $send_order_id){
+                $uv = (int)(Redis::hget('send_order_uv_'.$send_order_id,$day));
+                $pv = (int)(Redis::hget('send_order_pv_'.$send_order_id,$day));
+                $pvInfo = DB::table('send_order_uv_pv')->where('send_order_id',$send_order_id)->select('history_pv','history_uv','uv_reach_200_time','uv_reach_500_time')->first();
+                if($pvInfo){
+                    $total_uv = $pvInfo->history_uv+$uv;
+                    $total_pv = $pvInfo->history_pv+$pv;
+                    $update_data = [
+                        'history_pv'=>$total_pv,
+                        'history_uv'=>$total_uv,
+                        'updated_at'=>date('Y-m-d H:i:s')
+                    ];
+                    DB::table('send_order_uv_pv')->where('send_order_id',$send_order_id)->update($update_data);
+                }else{
+                    $insert_data = [
+                        'today_pv'=>0,
+                        'today_uv'=>0,
+                        'total_pv'=>$pv,
+                        'total_uv'=>$uv,
+                        'history_pv'=>$pv,
+                        'history_uv'=>$uv,
+                        'send_order_id'=>$send_order_id,
+                        'created_at'=>date('Y-m-d H:i:s'),
+                        'updated_at'=>date('Y-m-d H:i:s')
+                    ];
+                    if(abs($uv-200) <10){
+                        $insert_data['uv_reach_200_time'] = date('Y-m-d H:i:s');
+                    }
+                    if(abs($uv-500) <10){
+                        $insert_data['uv_reach_500_time'] = date('Y-m-d H:i:s');
+                    }
+                    DB::table('send_order_uv_pv')->insert($insert_data);
+                }
+            }
+        //}
+    }
+}

+ 177 - 0
app/Console/Commands/SendOrder/SendStatsEmail.php

@@ -0,0 +1,177 @@
+<?php
+
+namespace App\Console\Commands\SendOrder;
+
+use App\Modules\Book\Services\BookTagsService;
+use App\Modules\Statistic\Services\SendStatsEmailService;
+use Illuminate\Console\Command;
+use App\Modules\Message\MessageNotify;
+class SendStatsEmail extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sendOrderEmail';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送外部派单作品分析报表';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        //
+        $this->getSuperiorBooks();
+        return ;
+        $beginLastweek = date('Y-m-d',mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y')));
+        $endLastweek   = date('Y-m-d',mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y')));
+
+        $data = SendStatsEmailService::getOrderStats($beginLastweek,$endLastweek);
+
+        $page = view('email.weekOrderStats',['datas'=>$data]);
+        $html = response($page)->getContent();
+        //\Log::info($html);
+        $data_temp = array();
+        $header = ['书籍ID','书籍名称','UV','注册用户数','注册/UV','强关粉','强关率(强关/注册)','充值金额','付费人数','充值/UV','强关付费率(付费/强关)','UV付费率(付费/UV)','派单数','男女频'];
+        foreach ($data as $k=>$item) {
+            $title='';
+            switch ($k){
+                case 0:$title='注册UV比高于85%';break;
+                case 1:$title='注册UV比介于30%到85%';break;
+                case 2:$title='注册UV比低于30%';break;
+            }
+            $temp = array('header'=>$header,'title'=>$title,'data'=>array());
+            foreach ($item as $key=>$value) {
+                $temp['data'][] = array(
+                    $value['bid'],
+                    $value['book_name'],
+                    $value['UV'],
+                    $value['register_user_sum'],
+                    $value['UV']>0?(round($value['register_user_sum']/$value['UV'],4)*100).'%':0,
+                    $value['force_user_sum'],
+                    $value['register_user_sum']>0?(round($value['force_user_sum']/$value['register_user_sum'],4)*100).'%':0,
+                    $value['recharge_sum'],
+                    $value['pay_user_num'],
+                    $value['UV']>0?round($value['recharge_sum']/ $value['UV'],2):0,
+                    $value['force_user_sum']>0?(round($value['pay_user_num']/$value['force_user_sum'],4)*100).'%':0,
+                    $value['UV']>0?(round($value['pay_user_num']/$value['UV'],4)*100).'%':0,
+                    $value['send_orders_num'],
+                    $value['pid']
+                );
+            }
+            $data_temp[] = $temp;
+        }
+        $storage_file = 'app/last_week_send_order.xlsx';
+       saveExcelDataToMultiSheet($data_temp,storage_path($storage_file));
+
+        $to_user = array(
+            ['address'=>'songdb@iqiyoo.com','name'=>'songdb'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address' => 'zhoulj@iqiyoo.com', 'name' => '周灵杰'],
+        );
+
+        $to_users = '';
+        foreach ($to_user as $item){
+            $to_users .= $item['address'].";";
+        }
+
+
+        $notify = MessageNotify::mail([
+            'to_emails' => $to_users,
+            'subject' => "上周( $beginLastweek 至 $endLastweek )外部派单作品分析报表",
+            'body' => $html,
+            'delay_times' => 0,
+        ]);
+        $notify->addAttach($storage_file);
+        $notify->notify();
+        //SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>"上周( $beginLastweek 至 $endLastweek )外部派单作品分析报表",'body'=>$html],storage_path('app/last_week_send_order.xlsx'));
+    }
+
+    private function getSuperiorBooks() {
+        $data = SendStatsEmailService::getOrderStatsNew();
+
+        $page = view('email.daySendOrderStats',['datas'=>$data]);
+        $html = response($page)->getContent();
+        //\Log::info($html);
+        $data_temp = array();
+        $header = ['书籍ID','书籍名称','是否下架','篇幅','24小时uv','24小时充值总额','72小时uv','72小时充值总额','uv','24~72小时充值增长','24小时充值比24小时UV','72小时充值比24小时UV','强关率'];
+        foreach ($data as $k=>$item) {
+            $title='';
+            switch ($k){
+                case 0:$title='注册UV比高于85%';break;
+                //case 1:$title='注册UV比介于30%到85%';break;
+                case 1:$title='注册UV比低于30%';break;
+            }
+            $temp = array('header'=>$header,'title'=>$title,'data'=>array());
+            foreach ($item as $key=>$value) {
+                $temp['data'][] = array(
+                    $value['bid'],
+                    $value['book_name'],
+                    $value['is_on_shelf']==1?'内部上架':'外部上架',
+                    $value['charge_type']=='BOOK'?'短篇':'长篇',
+                    $value['uv_one_day_sum'],
+                    $value['recharge_amount_in_one_day'],
+                    $value['uv_three_day_sum'],
+                    $value['recharge_amount_in_three_days'],
+                    $value['UV'],
+                    $value['recharge_amount_in_one_day']>0?round(($value['recharge_amount_in_three_days']-$value['recharge_amount_in_one_day'])/$value['recharge_amount_in_one_day'],2):0,
+                    $value['uv_one_day_sum']>0?round(($value['recharge_amount_in_one_day']/$value['uv_one_day_sum']),2):0,
+                    //$value['uv_three_day_sum']>0?round(($value['recharge_amount_in_three_days']/$value['uv_three_day_sum']),2):0,
+                    $value['uv_one_day_sum']>0?round(($value['recharge_amount_in_three_days']/$value['uv_one_day_sum']),2):0,
+                    $value['register_user_sum']>0?(round(($value['force_user_sum']/$value['register_user_sum']),4)*100).'%':0,
+
+                );
+            }
+            $data_temp[] = $temp;
+        }
+        $storage_file = 'app/last_week_send_order.xlsx';
+        saveExcelDataToMultiSheet($data_temp,storage_path($storage_file));
+
+        $to_user = array(
+            ['address'=>'zhangzg@iqiyoo.com','name'=>'张总'],
+            ['address'=>'chensj@zw88.net','name'=>'陈帅君'],
+            ['address'=>'zhaojp@yqsd.net','name'=>'赵君平'],
+            ['address'=>'liur@iqiyoo.com','name'=>'刘嵘'],
+            ['address'=>'panxp@zw88.net','name'=>'潘霞萍'],
+            ['address'=>'2711046732@qq.com','name'=>'樊柯'],
+//            ['address'=>'lisy@zw88.net','name'=>'test'],
+
+        );
+
+
+        $to_users = '';
+        foreach ($to_user as $item){
+            $to_users .= $item['address'].";";
+        }
+
+
+        $notify = MessageNotify::mail([
+            'to_emails' => $to_users,
+            'subject' => '追书云'.date('Y-m-d',strtotime('-1 day'))."优质书外部派单分析报表",
+            'body' => $html,
+            'delay_times' => 0,
+        ]);
+        $notify->addAttach($storage_file);
+        $notify->notify();
+        //SendStatsEmailService::SendHtmlEmailWithAcce($to_user,['subject'=>'追书云'.date('Y-m-d',strtotime('-1 day'))."优质书外部派单分析报表",'body'=>$html],storage_path('app/last_week_send_order.xlsx'));
+    }
+}

+ 188 - 0
app/Console/Commands/SendOrder/SetExtraStats.php

@@ -0,0 +1,188 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: sogndb
+ * Date: 2018/02/05
+ * Time: 下午5:26
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use Log;
+use Illuminate\Console\Command;
+use App\Modules\SendOrder\Services\SendOrderService;
+use App\Modules\Statistic\Services\WapVisitStatService;
+use DB;
+use Redis;
+
+class SetExtraStats extends Command
+{
+    /**
+     * 执行命令   php artisan send_order:set_extra_stats
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'send_order:set_extra_stats';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '派单额外数据uv24小时设置';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        ini_set('memory_limit', '1024M');
+        print_r('memory_used:'.memory_get_usage()."\n");
+        print_r("======派单额外数据uv24小时设置 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        Log::info("======派单额外数据uv24小时设置 【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+
+        $start = date('Y-m-d H:i:s',strtotime('-1 day') - 120);
+        $end = date('Y-m-d H:i:s',strtotime($start)+240);
+        collect(DB::select("select send_orders.id,send_orders.send_time,uv_one_day from send_orders left join send_order_extra_stats on send_order_extra_stats.send_order_id = send_orders.id where send_orders.send_time >= '{$start}' and send_orders.send_time <= '{$end}'"))->each(function ($send_order){
+            if($send_order->uv_one_day === null)
+            {
+                $uv_one_day = $this->getOneDayUv($send_order->id);
+                $pv_one_day = $this->getOneDayPv($send_order->id);
+                $time = date('Y-m-d H:i:s');
+                $data = [
+                    'uv_one_day'=>$uv_one_day,
+                    'pv_one_day'=>$pv_one_day,
+                    'send_order_id'=>$send_order->id,
+                    'send_time'=>$send_order->send_time,
+                    'created_at'=>$time,
+                    'updated_at'=>$time
+                ];
+                DB::table('send_order_extra_stats')->insert($data);
+            }
+        });
+
+        $start = date('Y-m-d H:i:s',strtotime('-3 days') - 120);
+        $end = date('Y-m-d H:i:s',strtotime($start)+240);
+        collect(DB::select("select send_orders.id,send_orders.send_time,send_order_extra_stats.id as extra_id,uv_three_day from send_orders left join send_order_extra_stats on send_order_extra_stats.send_order_id = send_orders.id where send_orders.send_time >= '{$start}' and send_orders.send_time <= '{$end}'"))->each(function ($send_order){
+            if($send_order->uv_three_day === null)
+            {
+                $uv_three_day = $this->getThreeDayUv($send_order->id);
+                $pv_three_day = $this->getThreeDayPv($send_order->id);
+                $time = date('Y-m-d H:i:s');
+                $data = [
+                    'uv_three_day'=>$uv_three_day,
+                    'pv_three_day'=>$pv_three_day,
+                    'updated_at'=>$time
+                ];
+                DB::table('send_order_extra_stats')->where('id',$send_order->extra_id)->update($data);
+            }
+        });
+
+        Log::info("======派单额外数据uv24小时设置 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r("======派单额外数据uv24小时设置 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r('memory_used:'.memory_get_usage()."\n");
+    }
+
+    //采集24小时uv
+    private function getOneDayUv($id)
+    {
+        $today = date('Y-m-d');
+        $yesterday = date('Y-m-d',strtotime('-1 day'));
+
+        $one_day_uv = 0;
+        $redis_uv = Redis::hgetall('send_order_uv_'. $id);
+        $one_day_uv += isset($redis_uv[$today]) ? (int)$redis_uv[$today] : 0;//当天从redis获取
+
+        $yesterday_uv = isset($redis_uv[$yesterday]) ? (int)$redis_uv[$yesterday] : 0;
+        if(!$yesterday_uv)
+        {
+            //从数据库中获取v
+            $yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $yesterday);
+            $yesterday_uv = $yesterday_uv_pv['uv'];
+        }
+        $one_day_uv += $yesterday_uv;
+        return $one_day_uv;
+    }
+
+    //采集24小时pv
+    private function getOneDayPv($id)
+    {
+        $today = date('Y-m-d');
+        $yesterday = date('Y-m-d',strtotime('-1 day'));
+
+        $one_day_pv = 0;
+        $redis_pv = Redis::hgetall('send_order_pv_'. $id);
+        $one_day_pv += isset($redis_pv[$today]) ? (int)$redis_pv[$today] : 0;//当天从redis获取
+
+        $yesterday_pv = isset($redis_pv[$yesterday]) ? (int)$redis_pv[$yesterday] : 0;
+        if(!$yesterday_pv)
+        {
+            //从数据库中获取
+            $yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $yesterday);
+            $yesterday_pv = $yesterday_uv_pv['pv'];
+        }
+        $one_day_pv += $yesterday_pv;
+        return $one_day_pv;
+    }
+
+    //采集72小时uv
+    private function getThreeDayUv($id)
+    {
+        $today = date('Y-m-d');
+        $yesterday = date('Y-m-d',strtotime('-1 day'));
+        $the_day_before_yesterday = date('Y-m-d',strtotime('-2 day'));
+        $three_days_ago = date('Y-m-d',strtotime('-3 day'));
+
+        $one_day_uv = 0;
+        $redis_uv = Redis::hgetall('send_order_uv_'. $id);
+        $one_day_uv += isset($redis_uv[$today]) ? (int)$redis_uv[$today] : 0;//当天从redis获取
+
+        $yesterday_uv = isset($redis_uv[$yesterday]) ? (int)$redis_uv[$yesterday] : 0;
+        if(!$yesterday_uv)
+        {
+            //从数据库中获取v
+            $yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $yesterday);
+            $yesterday_uv = $yesterday_uv_pv['uv'];
+        }
+        $one_day_uv += $yesterday_uv;
+
+        $the_day_before_yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $the_day_before_yesterday);
+        $one_day_uv += $the_day_before_yesterday_uv_pv['uv'];
+        $three_days_ago_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $three_days_ago);
+        $one_day_uv += $three_days_ago_uv_pv['uv'];
+        return $one_day_uv;
+    }
+
+    //采集72小时pv
+    private function getThreeDayPv($id)
+    {
+        $today = date('Y-m-d');
+        $yesterday = date('Y-m-d',strtotime('-1 day'));
+        $the_day_before_yesterday = date('Y-m-d',strtotime('-2 days'));
+        $three_days_ago = date('Y-m-d',strtotime('-3 days'));
+
+        $one_day_pv = 0;
+        $redis_pv = Redis::hgetall('send_order_pv_'. $id);
+        $one_day_pv += isset($redis_pv[$today]) ? (int)$redis_pv[$today] : 0;//当天从redis获取
+
+        $yesterday_pv = isset($redis_pv[$yesterday]) ? (int)$redis_pv[$yesterday] : 0;
+        if(!$yesterday_pv)
+        {
+            //从数据库中获取
+            $yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $yesterday);
+            $yesterday_pv = $yesterday_uv_pv['pv'];
+        }
+        $one_day_pv += $yesterday_pv;
+
+        $the_day_before_yesterday_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $the_day_before_yesterday);
+        $one_day_pv += $the_day_before_yesterday_uv_pv['pv'];
+        $three_days_ago_uv_pv = WapVisitStatService::getSendOrderDayUvPvFromStat($id, $three_days_ago);
+        $one_day_pv += $three_days_ago_uv_pv['pv'];
+        return $one_day_pv;
+    }
+
+}

+ 62 - 0
app/Console/Commands/SendOrder/StatSendOrderByDate.php

@@ -0,0 +1,62 @@
+<?php
+
+
+namespace App\Console\Commands\SendOrder;
+
+
+use App\Modules\SendOrder\Services\SendOrderChargeStatService;
+use Illuminate\Console\Command;
+
+class StatSendOrderByDate extends Command
+{
+    /**
+     * 执行命令   php artisan send_order:generate_day_stat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'send_order_recharge_stat {--start_date=} {--end_date=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '派单充值数据统计';
+
+    /**
+     * @return bool
+     */
+    public function handle(): bool
+    {
+        $date       = date('Y-m-d', strtotime('-1 days'));
+        $start_date = $this->option('start_date');
+        $end_date   = $this->option('end_date');
+
+        // 根据参数判断
+        if ($start_date && $end_date && $start_date <= $end_date) {
+            while (strtotime($start_date) <= strtotime($end_date)) {
+                var_dump($start_date);
+
+                // 删除旧数据
+                SendOrderChargeStatService::deleteSendOrderStatsByDate($start_date);
+
+                // 执行
+                SendOrderChargeStatService::getOrdersByDate($start_date);
+
+                // 自增1天
+                $start_date = date('Y-m-d', strtotime('+1 days', strtotime($start_date)));
+            }
+        } else {
+            // 删除旧数据
+            SendOrderChargeStatService::deleteSendOrderStatsByDate($date);
+
+            // 执行
+            SendOrderChargeStatService::getOrdersByDate($date);
+        }
+
+        return true;
+    }
+
+}

+ 93 - 0
app/Console/Commands/SendOrder/UpdateSendOrderPreSendDate.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Console\Commands\SendOrder;
+use App\Modules\SendOrder\Services\SendOrderService;
+use App\Modules\SendOrder\Models\SendOrder;
+use App\Modules\Sys\Services\PromotionGroupConfigService;
+use Illuminate\Console\Command;
+use App\Modules\Util;
+use Log;
+class UpdateSendOrderPreSendDate extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'updateSendOrderPreSendDate{--pre_date=}{--id=*}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新派单预计发送时间';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        if($this->option('id'))
+        {
+            $distribution_channel_ids=$this->option('id');
+        }else{
+            $distribution_channel_ids = explode(',', PromotionGroupConfigService::CHANNEL_ID_LIST());
+            $distribution_channel_ids = [2,14,13,188];
+        }
+        if($this->option('pre_date')){
+            $pre_date=$this->option('pre_date');
+        }
+
+        $params = compact('distribution_channel_ids', 'show_agent','pre_date');
+//        $params['promotion_type'] = 'EXTERNAL'; //只筛选外部
+        $data = SendOrderService::searchForDaliy($params, true);
+        $ids ='';
+        $count=0;
+        foreach ($data as $item) {
+            $item->old_name = $item->name;
+            if (strpos($item->name, "-")) {
+                $strs = explode('-', $item->name);
+                if (count($strs) == 4) {
+                    $date_str = $strs[2];
+//                    dump($item->name.' '.$item->id.' '.$date_str.' '.date('Y/m/d',strtotime($date_str)));
+                    if($date_str==date('Y/m/d',strtotime($date_str))){
+                        $item->real_pre_send_date = date('Y/m/d',strtotime($date_str));
+                    }
+                }elseif (count($strs) == 6) {
+                    $date_str = $strs[2] .'-'.$strs[3] .'-'.$strs[4];
+//                    dump($item->name.' '.$item->id.' '.$date_str.' '.date('Y-m-d',strtotime($date_str)));
+                    if ($date_str == date('Y-m-d', strtotime($date_str))) {
+                        $item->real_pre_send_date = date('Y/m/d', strtotime($date_str));
+                    }
+                }
+                if(isset($item->real_pre_send_date)&&(date('Y-m-d',strtotime($item->real_pre_send_date))!=date('Y-m-d',strtotime($item->pre_send_date))||empty($item->pre_send_date))){
+
+//                    dump($item->id.' '.' : '.date('Y-m-d',strtotime($item->real_pre_send_date)).'  '.date('Y-m-d',strtotime($item->pre_send_date)));
+
+                    $effect = SendOrder::where('id',$item->id)->update(['pre_send_date'=>date('Y-m-d',strtotime($item->real_pre_send_date))]);
+                    $ids =$ids.' '.$item->id;
+                    $count+=$effect;
+                }
+            }
+        }
+        if($count){
+            dump("共修改了{$count} 项数据,id为{$ids}");
+            Log::info("共修改了{$count}项数据,id为{$ids}");
+        }
+
+
+    }
+}

+ 84 - 0
app/Console/Commands/SendOrder/UserActivityStats.php

@@ -0,0 +1,84 @@
+<?php
+/**
+用户活跃统计
+ */
+
+namespace App\Console\Commands\SendOrder;
+
+use Log;
+use Illuminate\Console\Command;
+use App\Modules\User\Services\ReadRecordService;
+use App\Modules\User\Services\UserService;
+
+use DB;
+
+class UserActivityStats extends Command
+{
+    /**
+     * 执行命令   php artisan SendOrder:userActivityStat
+     *
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SendOrder:userActivityStat  {loop} {loop_add}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '月活统计';
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        ini_set('memory_limit', '1024M');
+        print_r('memory_used:'.memory_get_usage()."\n");
+        print_r("======月活统计【任务执行开始】=====".date("y-m-d H:i:s"."\n"));
+        
+        $base_loop = $loop = $this->argument('loop');
+        $loop_add = $this->argument('loop_add');
+        
+        $one_month_ago = strtotime(date('Y-m-d'))-30*24*3600;
+        $start = date('Y-m-d',strtotime('-30 day'));
+        $end = date('Y-m-d');
+        
+        
+        $loop_end = $loop+$loop_add;
+        $limit = 10000;
+        $active_user_num = 0;
+        \Log::info('userActivityStat_start:loop:'.$loop.' active_user_num:'.$active_user_num);
+        
+        while($loop < 3000 && $loop < $loop_end){
+        	// 获取用户,每次1w
+        	$offset = $limit*($loop-1);
+        	$users = UserService::getUserList($limit,$offset);
+        	if(is_null($users)){
+        		\Log::info('userActivityStat_break:base_loop:'.$base_loop.' loop:'.$loop.' active_user_num:'.$active_user_num);
+        		break;
+        	}
+        	foreach($users as $user){
+        		// 获取最近阅读时间
+        		$read_recodes = ReadRecordService::getReadRecord($user->id);
+//         		\Log::info($read_recodes);
+        		$last_read_time = isset($read_recodes[0]['time'])?$read_recodes[0]['time']:'0';
+        		//\Log::info('last_read_time:'.$last_read_time.' one_month_ago:'.$one_month_ago);
+        		// 如果再一个月内
+        		if($last_read_time > 0 && $last_read_time > $one_month_ago){
+        			$active_user_num ++;
+        		}
+        	}
+        	\Log::info('userActivityStat:loop:base_loop:'.$base_loop.' loop:'.$loop.' active_user_num:'.$active_user_num);
+        	$loop++;
+        }
+        \Log::info('userActivityStat_end_base_loop:'.$base_loop.' loop:'.$loop.' active_user_num:'.$active_user_num);
+        
+        print_r("======月活统计 【任务执行结束】=====".date("y-m-d H:i:s"."\n"));
+        print_r('memory_used:'.memory_get_usage()."\n");
+    }
+}

+ 59 - 0
app/Console/Commands/SendOrderBreakevenForceUser.php

@@ -0,0 +1,59 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+class SendOrderBreakevenForceUser extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sendorderbreadforceuser';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新粉丝数';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->start();
+    }
+
+    public function start(){
+        DB::table('send_order_breakeven_stats')->select('id','official_account_id','date')->where('date','=',date('Y-m-d',time()-86400))->orderBy('id')->chunk(1000,function ($res){
+            foreach ($res as $v){
+                $appid = DB::table('official_accounts')->where('id',$v->official_account_id)->select('appid')->first();
+                if($appid && isset($appid->appid)){
+                    $total = DB::table('force_subscribe_users')->where('is_subscribed',1)->where('appid',$appid->appid)->count();
+                    $today = DB::table('force_subscribe_users')
+                        ->where('appid',$appid->appid)
+                        ->where('created_at','>=',$v->date)
+                        ->where('created_at','<=',$v->date.' 23:59:59')
+                        ->count();
+                    DB::table('send_order_breakeven_stats')->where('id',$v->id)->update(['total_force_user_num'=>$total,'force_user_num'=>$today]);
+                }
+            }
+        });
+    }
+}

+ 53 - 0
app/Console/Commands/SendServiceMsg.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class SendServiceMsg extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sendservicemsg';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '发送客服消息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->sendStart();
+        $this->sendStartPoint();
+    }
+
+    
+    public function sendStart(){
+        CustomMsgService::add_news_top_book();
+    }
+
+    public function sendStartPoint(){
+        CustomMsgService::add_news_point_book();
+    }
+
+}

+ 133 - 0
app/Console/Commands/SignReward.php

@@ -0,0 +1,133 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Modules\User\Services\UserSignService;
+use Illuminate\Console\Command;
+use DB;
+use Redis;
+use App\Jobs\SendTexts;
+use App\Modules\User\Services\ReadRecordService;
+use App\Modules\User\Services\UserService;
+use App\Modules\Book\Services\BookConfigService;
+use Hashids;
+use App\Modules\Activity\Models\Activity;
+use App\Modules\Activity\Services\ActivityService;
+class SignReward extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'sign:reward {--record}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '签到奖励';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $option = $this->option('record');
+        if($option){
+            $this->signRecord();
+        }else{
+            $this->signPushMsg();
+        }
+    }
+
+    public function saveSignInfoAndReward($option)
+    {
+        if ($option) {
+            $sign_key = 'sign-' . date('Y-m-d', time() - 86400);
+        } else {
+            $sign_key = 'sign-' . date('Y-m-d');
+        }
+        //print_r($sign_key);
+        //return 1;
+        $res = Redis::hgetall($sign_key);
+        $sign_data = [];
+        $uid_arr = [];
+        if (!$res) return -1;
+
+        foreach ($res as $key => $v) {
+            if (Redis::SISMEMBER($sign_key, $key)) {
+                continue;
+            }
+            $uid_arr[] = $key;
+            $sign_data[] = ['uid' => $key, 'price' => 50, 'sign_time' => $v, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s')];
+            Redis::sadd($sign_key, $key);
+        }
+        DB::table('user_sign')->insert($sign_data);
+        DB::table('users')->whereIn('id', $uid_arr)->increment('balance', 50);
+        DB::table('users')->whereIn('id', $uid_arr)->increment('reward_balance', 50);
+        return 0;
+    }
+
+    public function signRecord(){
+        DB::table('order_day_stats')->select('id', 'distribution_channel_id', 'date')->where('date',date('Y-m-d',time()-86400))->orderBy('id')->chunk(1000, function ($res) {
+            foreach ($res as $v) {
+                $sql = "select count(*) as count from user_sign join users on user_sign.uid=users.id where date(user_sign.created_at)='%s' and user.distribution_channel_id=%s";
+                $user_sign_info = DB::select($sql);
+                DB::table('order_day_stats')->where('id',$v->id)->update([
+                    'sign_num'=>(int)$user_sign_info[0]->count
+                ]);
+            }
+        });
+    }
+
+    public function signPushMsg()
+    {
+        $sign_key = 'leyuee:wap:usersigni';
+        //Redis::sadd($sign_key, 9);
+        $records = Redis::hgetall($sign_key);
+        if ($records ) {
+            //$uids = Redis::SMEMBERS($sign_key);
+            Redis::del($sign_key);
+            $uids = [];
+            foreach ($records as $u=>$p){
+                $uids[] = $u;
+            }
+            if (empty($uids)) return false;
+            $subscribe_user = DB::table('force_subscribe_users')->whereIn('uid', $uids)->where('is_subscribed', 1)->select('uid', 'appid', 'openid', 'distribution_channel_id')->get();
+            if ($subscribe_user) {
+                $delay = 0;
+                foreach ($subscribe_user as $keys => $value) {
+                    $content = UserSignService::userSignReturnContent3($value->openid);
+                    $data['openid'] = $value->openid;
+                    $data['appid'] = $value->appid;
+                    $data['content'] = $content;
+                    $data['type'] = 'one_task';
+                    $data['send_time'] = date("Y-m-d H:i:s");
+                    $data['task_id'] = md5(123);
+                    $send_data = array(
+                        'send_time' => date("Y-m-d H:i:s"),
+                        'data' => $data
+                    );
+                    //print_r($send_data);
+                    dispatch((new SendTexts($send_data))->onConnection('rabbitmq')->delay($delay)->onQueue('send_texts_list'));
+                }
+            }
+            return false;
+        }
+        return false;
+    }
+}

+ 47 - 0
app/Console/Commands/SmartPush/AllPushHotBook.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class AllPushHotBook extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:AllPushHotBook';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '已付费推送热门书籍';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	$this->all_push_hot_book();
+    }
+
+    public function all_push_hot_book(){
+    	CustomMsgService::SmartPush('all_hot_push');
+    }
+
+}

+ 47 - 0
app/Console/Commands/SmartPush/LongChapterCustom.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class LongChapterCustom extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:LongChapterCustom';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '推送长篇客服';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+//     	$this->LongChapterCustom();
+    }
+
+    public function LongChapterCustom(){
+    	CustomMsgService::SimpleSmartPush('custom_short_long_chapter');
+    }
+
+}

+ 48 - 0
app/Console/Commands/SmartPush/LongChapterTemplate.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class LongChapterTemplate extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:LongChapterTemplate';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '推送长篇模板';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	// 暂停
+//     	$this->LongChapterTemplate();
+    }
+
+    public function LongChapterTemplate(){
+    	CustomMsgService::SimpleSmartPush('template_short_long_chapter');
+    }
+
+}

+ 47 - 0
app/Console/Commands/SmartPush/PaidPushPointBook.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class PaidPushPointBook extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:PaidPushPointBook';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '已付费推送定制书籍';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	$this->paid_push_point_book();
+    }
+
+    public function paid_push_point_book(){
+    	CustomMsgService::SmartPush('paid_point_push');
+    }
+
+}

+ 47 - 0
app/Console/Commands/SmartPush/PaidUserCustom.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class PaidUserCustom extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:PaidUserCustom';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '已付费用户6小时后推送客服消息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	$this->pay_user_custom();
+    }
+
+    public function pay_user_custom(){
+    	CustomMsgService::SmartPush('pay_daily_push');
+    }
+
+}

+ 47 - 0
app/Console/Commands/SmartPush/UnPaidPushHotBook.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class UnPaidPushHotBook extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:UnPaidPushHotBook';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '未付费推送热门书籍';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	$this->unpaid_push_hot_book();
+    }
+
+    public function unpaid_push_hot_book(){
+    	CustomMsgService::SmartPush('unpaid_hot_push');
+    }
+
+}

+ 47 - 0
app/Console/Commands/SmartPush/UnPaidPushPointBook.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class UnPaidPushPointBook extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:UnPaidPushPointBook';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '未付费推送定制书籍';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+    	$this->unpaid_push_point_book();
+    }
+
+    public function unpaid_push_point_book(){
+    	CustomMsgService::SmartPush('unpaid_point_push');
+    }
+
+}

+ 46 - 0
app/Console/Commands/SmartPush/UnPaidUserBigActivity.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class UnPaidUserBigActivity extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:UnPaidUserBigActivity';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '未支付新用户优惠充值活动(更多充值选项 )';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->unPaidUserBigActivity();
+    }
+
+    public function unPaidUserBigActivity(){
+        CustomMsgService::SmartPush('unpaid_send_big_activity');
+    }
+}

+ 46 - 0
app/Console/Commands/SmartPush/UnPaidUserSmallActivity.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use Illuminate\Console\Command;
+use App\Modules\OfficialAccount\Services\CustomMsgService;
+class UnPaidUserSmallActivity extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'SmartPush:UnPaidUserSmallActivity';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '未支付新用户9.9充值活动';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->unPaidUserActivity();
+    }
+
+    public function unPaidUserActivity(){
+    	CustomMsgService::SmartPush('unpaid_send_activity');
+    }
+}

+ 138 - 0
app/Console/Commands/SmartPush/UpdateMediaPushRechargeInfo.php

@@ -0,0 +1,138 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use App\Modules\MediaPush\Models\MediaPushDayStats;
+use App\Modules\MediaPush\Models\OrderParam;
+use App\Modules\PersonalOp\Models\MediaPushDetailRecord;
+use DB;
+use Illuminate\Console\Command;
+
+class UpdateMediaPushRechargeInfo extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'update_media_push_recharge_info';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新个性化推送带来的充值';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->updateOneDayRechargeInfo();
+        $this->updateThreeDayRechargeInfo();
+    }
+
+
+    public function updateOneDayRechargeInfo()
+    {
+        $start_time = $date = date('Y-m-d H:i:s', strtotime('-1 day'));
+        $params = ['is_one_day' => 1, 'start_time' => $start_time];
+        $info = MediaPushDetailRecord::getUnUpdatedInfos($params);
+
+        $officialChargeAmountArray = [];
+        foreach ($info as $item) {
+            $push_time = $item->push_time;
+            $promotion_id = $item->promotion_id;
+            $end_time = date('Y-m-d H:i:s', strtotime($item->push_time) + 86400);
+            $params = ['start_time' => $push_time, 'end_time' => $end_time, 'promotion_id' => $promotion_id];;
+            $recharge_in_one_day = OrderParam::getChargeAmount($params);
+            $item->recharge_in_one_day = $recharge_in_one_day;
+            $item->save();
+
+            //更新dayStats表
+            $appid = $item->appid;
+            $date = date('Y-m-d', strtotime($item->push_time));
+            if (isset($officialChargeAmountArray[$date][$appid])) {
+                $officialChargeAmountArray[$date][$appid] = $officialChargeAmountArray[$date][$appid] + $recharge_in_one_day;
+            } else {
+                $officialChargeAmountArray[$date][$appid] = $recharge_in_one_day;
+            }
+        }
+
+        foreach ($officialChargeAmountArray as $k => $v) {
+            foreach ($v as $index => $value) {
+                $date = $k;
+                $appid = $index;
+                $recharge_in_one_day = $value;
+
+                $mediaPushDayInfo = MediaPushDayStats::getByAppidAndDate($appid, $date);
+                if ($mediaPushDayInfo) {
+                    if (empty($mediaPushDayInfo->recharge_in_one_day)) {
+                        $mediaPushDayInfo->recharge_in_one_day = $recharge_in_one_day;
+                    } else {
+                        $mediaPushDayInfo->recharge_in_one_day += $recharge_in_one_day;
+                    }
+                    $mediaPushDayInfo->save();
+                }
+            }
+        }
+    }
+
+    public function updateThreeDayRechargeInfo()
+    {
+        $start_time = $date = date('Y-m-d H:i:s', strtotime('-3 day'));
+        $params = ['is_three_day' => 1, 'start_time' => $start_time];
+        $info = MediaPushDetailRecord::getUnUpdatedInfos($params);
+        $officialChargeAmountArray = [];
+        foreach ($info as $item) {
+            $push_time = $item->push_time;
+            $promotion_id = $item->promotion_id;
+            $end_time = date('Y-m-d H:i:s', strtotime($item->push_time) + 3 * 86400);
+            $params = ['start_time' => $push_time, 'end_time' => $end_time, 'promotion_id' => $promotion_id];;
+            $recharge_in_three_days = OrderParam::getChargeAmount($params);
+            $item->recharge_in_three_days = $recharge_in_three_days;
+            $item->save();
+
+            //更新dayStats表
+            $appid = $item->appid;
+            $date = date('Y-m-d', strtotime($item->push_time));
+
+            if (isset($officialChargeAmountArray[$date][$appid])) {
+                $officialChargeAmountArray[$date][$appid] = $officialChargeAmountArray[$date][$appid] + $recharge_in_three_days;
+            } else {
+                $officialChargeAmountArray[$date][$appid] = $recharge_in_three_days;
+            }
+        }
+
+        foreach ($officialChargeAmountArray as $k => $v) {
+            foreach ($v as $index => $value) {
+                $date = $k;
+                $appid = $index;
+                $recharge_in_three_days = $value;
+
+                $mediaPushDayInfo = MediaPushDayStats::getByAppidAndDate($appid, $date);
+                if ($mediaPushDayInfo) {
+                    if (empty($mediaPushDayInfo->recharge_in_three_days)) {
+                        $mediaPushDayInfo->recharge_in_three_days = $recharge_in_three_days;
+                    } else {
+                        $mediaPushDayInfo->recharge_in_three_days = $mediaPushDayInfo->recharge_in_three_days + $recharge_in_three_days;
+                    }
+                    $mediaPushDayInfo->save();
+                }
+            }
+        }
+    }
+}

+ 84 - 0
app/Console/Commands/SmartPush/UpdateRecommandBooks.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace App\Console\Commands\SmartPush;
+
+use App\Modules\MediaPush\Models\MediaPushBookConfigs;
+use App\Modules\MediaPush\Models\MediaPushRelationBooks;
+use Illuminate\Console\Command;
+use DB;
+
+class UpdateRecommandBooks extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'update_recommand_books';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '更新图书推送的书籍信息';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->updateRecommandBooks();
+    }
+
+    /**
+     * 获取推荐的书籍
+     */
+    public function updateRecommandBooks()
+    {
+        $bids = MediaPushBookConfigs::getBids();;
+        $whereInBids = '(';
+        foreach ($bids as $bidItem) {
+            $whereInBids = $whereInBids . $bidItem->bid . ',';
+        }
+        $str_count = strlen($whereInBids);
+        if ($str_count > 2) {
+            $whereInBids = substr($whereInBids, 0, $str_count - 1);
+        }
+        $whereInBids .= ')';
+
+
+        if ($bids) {
+            $pro_bids = '';
+            foreach ($bids as $item) {
+                $bid = $item->bid;
+                $sql = "select bid,count(*) as user_count from deep_read_records where bid <>{$bid} and bid in {$whereInBids} and uid in (select uid from deep_read_records where bid='{$bid}') GROUP BY bid ORDER BY user_count desc limit 5";
+                $result = DB::select($sql);
+                if ($result) {
+                    foreach ($result as $book_item) {
+                        $pro_bids = $pro_bids . $book_item->bid;
+                        $pro_bids = $pro_bids . ',';
+                    }
+                    $pro_bids = substr($pro_bids, 0, strlen($pro_bids) - 1);
+                    $updated_at = date("Y-m-d H:i:s");
+                    $created_at = date("Y-m-d H:i:s");
+                    $updateParam = compact('pro_bids', 'updated_at','created_at');
+                    MediaPushRelationBooks::createdOrUpdated(compact('bid'), $updateParam);
+                    $pro_bids = '';
+                }
+            }
+        }
+    }
+}

+ 123 - 0
app/Console/Commands/SubscribeAlert.php

@@ -0,0 +1,123 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use App\Libs\SMS;
+use Illuminate\Support\Facades\Cache;
+use DB;
+class SubscribeAlert extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'subscribealert {--type=}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '粉丝和强关预警';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $type = $this->option('type');
+        if($type == 'getTopAlert'){
+            $this->getTopAlert();
+        }
+        if($type == 'subscribeRateAlert'){
+            $this->subscribeRateAlert();
+        }
+    }
+
+    /**
+     * 商户平台日粉丝到达上限90%、达到总上限90%
+     */
+    private function getTopAlert(){
+        $sql = "SELECT distribution_channel_id,GROUP_CONCAT(nickname)as nickname,GROUP_CONCAT(appid) as appid,SUM(subscribe_day_maximum) as `max` FROM official_accounts WHERE is_auth = 1 and is_enabled = 1 GROUP BY distribution_channel_id";
+        $res = DB::select($sql);
+        foreach ($res as $v){
+            $count = DB::table('force_subscribe_users')
+                ->whereIn('appid',explode(',',$v->appid))
+                ->where('is_subscribed',1)
+                ->where('created_at','>=',date('Y-m-d'))
+                ->where('created_at','<',date('Y-m-d',time()+86400))
+                ->count();
+            if($count>= $v->max*0.9){
+                $key = date('Y-m-d').'-distribution_channel_id-'.$v->distribution_channel_id;
+                $old = Cache::store('file')->get($key);
+
+                if($old){
+                    continue;
+                }else{
+                    Cache::store('file')->put($key,time(),24*60);
+                    $content = '强关峰值预警,渠道'.$v->distribution_channel_id.'日粉丝到达上限90%,公众号:'.$v->nickname;
+                    $this->send($content);
+                }
+            }
+            return;
+        }
+    }
+
+    private function send($content){
+        //(君平15858178353  张总 13858057394      陈帅军15088790066  zw 186.. 栋波15868100210 )
+        $phones = ['15858178353','18668420256','15868100210'];
+        //$phones = ['18668029091'];
+        foreach ($phones as $phone){
+            SMS::send($phone,$content);
+        }
+    }
+
+    public function subscribeRateAlert(){
+
+        $key = 'getSubscribeRate';
+        $old = Cache::store('file')->get($key);
+        if($old){
+            return;
+        }
+        $now_hour = date('G');
+        //echo '$now_hour--'.$now_hour.PHP_EOL;
+        $rate = $this->getSubscribeRate();
+        //echo '$tate is:'.$rate.PHP_EOL;
+        if($now_hour>=4 &&  $now_hour<=7){
+            if($rate < 0.2){
+                $content = '平台强关率预警,当前强关率'.$rate;
+                $this->send($content);
+                Cache::store('file')->put($key,time(),60*3);
+            }
+        }else{
+            if($rate < 0.25){
+                $content = '平台强关率预警,当前强关率'.$rate;
+                $this->send($content);
+                Cache::store('file')->put($key,time(),60*3);
+            }
+        }
+    }
+
+    private function getSubscribeRate(){
+        $register_user_num = DB::table('users')->where('created_at','>=',date('Y-m-d H',time()-3600))->where('created_at','<',date('Y-m-d H'))->count();
+        $force_subscribe_users_num = DB::table('force_subscribe_users')->where('created_at','>=',date('Y-m-d H',time()-3600))->where('created_at','<',date('Y-m-d H'))->count();
+        if($register_user_num == 0){
+            return 0;
+        }
+        return round($force_subscribe_users_num/$register_user_num,2);
+    }
+}

+ 117 - 0
app/Console/Commands/SubscribeDataStats.php

@@ -0,0 +1,117 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+use DB;
+use Log;
+class SubscribeDataStats extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'book:subds {--all}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = 'Command description';
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $options = $this->option('all');
+        if($options){
+            $this->resetAll();
+        }else{
+            $this->start();
+        }
+    }
+
+    private function _update($data){
+        $sql_fromat = 'select sum(sum_fee) as sum_fee, sum(sum_charge_balance) as sum_charge_balance, sum(sum_reward_balance) as sum_reward_balance from sub_bak5 where bid=%s and send_order_id=%s';
+        $sql = sprintf($sql_fromat,$data['bid'],$data['send_order_id']);
+        $chapter = DB::connection('chapter_order_mysql')->select($sql);
+
+        $sqls_fromat = 'select sum(fee) as sum_fee, sum(charge_balance) as sum_charge_balance, sum(reward_balance) as sum_reward_balance from book_orders where bid=%s and send_order_id=%s';
+        $sqls = sprintf($sqls_fromat,$data['bid'],$data['send_order_id']);
+        $book = DB::select($sqls);
+
+        $total_fee = 0;
+        $charge_balance = 0;
+        $rewrad_blance = 0;
+        if($chapter && isset($chapter[0])){
+            $total_fee += (int)$chapter[0]->sum_fee;
+            $charge_balance += (int)$chapter[0]->sum_charge_balance;
+            $rewrad_blance += (int)$chapter[0]->sum_reward_balance;
+        }
+
+        if($book && isset($book[0])){
+            $total_fee += (int)$book[0]->sum_fee;
+            $charge_balance += (int)$book[0]->sum_charge_balance;
+            $rewrad_blance += (int)$book[0]->sum_reward_balance;
+        }
+
+        DB::table('send_orders_stats')->where('id',$data['id'])->update([
+            'sum_fee'=>$total_fee,
+            'sum_charge_balance'=>$charge_balance,
+            'sum_reward_balance'=>$rewrad_blance
+        ]);
+    }
+
+    public function start(){
+        $date = date('Y-m-d',time()-86400);
+        $sql_fromat = 'select bid,send_order_id,sum(sum_fee) as sum_fee, sum(sum_charge_balance) as sum_charge_balance, sum(sum_reward_balance) as sum_reward_balance from sub_bak5 where date="%s"  group BY bid,send_order_id ';
+        $sql = sprintf($sql_fromat,$date);
+        $chapter = DB::connection('chapter_order_mysql')->select($sql);
+
+        foreach ($chapter as $c){
+            $update_temp = 'update send_orders_stats set sum_fee=sum_fee+'.(int)$c->sum_fee.', sum_charge_balance=sum_charge_balance+'.(int)$c->sum_charge_balance.',sum_reward_balance=sum_reward_balance+'.(int)$c->sum_reward_balance.' where bid='.(int)$c->bid.' and send_order_id='.(int)$c->send_order_id;
+            DB::update($update_temp);
+        }
+        $start_date = $date;
+        $end_date = date('Y-m-d');
+        $sqls = "select bid,send_order_id,sum(fee) as sum_fee, sum(charge_balance) as sum_charge_balance, sum(reward_balance) as sum_reward_balance from book_orders where created_at >='{$start_date}' and created_at <'{$end_date}'  GROUP BY bid,send_order_id";
+        $book = DB::select($sqls);
+
+        foreach ($book as $b){
+            $update_temp = 'update send_orders_stats set sum_fee=sum_fee+'.(int)$b->sum_fee.', sum_charge_balance=sum_charge_balance+'.(int)$b->sum_charge_balance.',sum_reward_balance=sum_reward_balance+'.(int)$b->sum_reward_balance.' where bid='.(int)$b->bid.' and send_order_id='.(int)$b->send_order_id;
+            DB::update($update_temp);
+        }
+    }
+
+    public function resetAll()
+    {
+        DB::table('send_orders_stats')->select('id', 'send_order_id', 'bid')->orderBy('id')->chunk(1000, function ($res) {
+            foreach ($res as $v) {
+                if ($v->send_order_id && $v->bid) {
+                    $this->_update([
+                        'id' => $v->id,
+                        'send_order_id' => $v->send_order_id,
+                        'bid' => $v->bid
+                    ]);
+                }
+            }
+        });
+    }
+
+
+}

+ 0 - 0
app/Console/Commands/SuperiorBooks/DailyScanForSupriorNewBook.php


Some files were not shown because too many files changed in this diff