Browse Source

用户统计

zqwang 1 year ago
parent
commit
00210cce1f

+ 43 - 0
app/Console/Commands/Statistic/OptimizerDayUserStatistic.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * 优化师新增用户统计
+ * @file:PromotionDayUserStatistic.php
+ * @Date: 2023/6/25
+ * @Time: 16:38
+ */
+
+
+namespace App\Console\Commands\Statistic;
+
+use Illuminate\Console\Command;
+use Modules\Common\Services\Statistic\OptimizerDayUser;
+
+class OptimizerDayUserStatistic extends Command
+{
+
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'Statistic:OptimizerDayUser {--date= : 统计日期}';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '优化师当日新增用户日统计';
+
+    /**
+     * Execute the console command.
+     */
+    public function handle(): void
+    {
+
+        $date = $this->option('date') ?? date('Y-m-d', strtotime('yesterday'));
+        $this->info('统计开始--统计日期:'.$date);
+        OptimizerDayUser::optimizerDayUserStatistic($date);
+        $this->info('统计结束');
+    }
+}

+ 2 - 0
app/Console/Kernel.php

@@ -22,6 +22,8 @@ class Kernel extends ConsoleKernel
         $schedule->command('Jiesuan:CompanyChargeDayJiesuan', [
             '--date' => date('Y-m-d', strtotime('yesterday'))
         ])->dailyAt('01:00');
+        // 新增用户统计
+        $schedule->command('Statistic:OptimizerDayUser')->dailyAt('05:00');
     }
 
     /**

+ 1 - 1
config/database.php

@@ -56,7 +56,7 @@ return [
             'collation' => 'utf8mb4_unicode_ci',
             'prefix' => env('DB_PREFIX', ''),
             'prefix_indexes' => true,
-            'strict' => true,
+            // 'strict' => true,
             'engine' => 'InnoDB',
             'options' => extension_loaded('pdo_mysql') ? array_filter([
                 PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),

+ 16 - 0
modules/Common/Models/TjCompanyDayNewUser.php

@@ -0,0 +1,16 @@
+<?php
+/**
+ *
+ * @file:OptimizerDayUser.php
+ * @Date: 2023/6/26
+ * @Time: 11:04
+ */
+
+
+namespace Modules\Common\Models;
+
+class TjCompanyDayNewUser extends BaseModel
+{
+    protected $table = "tj_company_day_new_users";
+    protected $fillable = ["id","date","user_id","miniprogram_id","new_user_recharge_coin_num","miniprogram_name","miniprogram_play_name","miniprogram_type","new_user_num","new_user_recharge_num","new_user_recharge_vip_num","new_user_recharge_total","recharge_user_total","recharge_amount_total","updated_at","created_at"];
+}

+ 16 - 0
modules/Common/Models/TjOptimizerDayNewUser.php

@@ -0,0 +1,16 @@
+<?php
+/**
+ *
+ * @file:OptimizerDayUser.php
+ * @Date: 2023/6/26
+ * @Time: 11:04
+ */
+
+
+namespace Modules\Common\Models;
+
+class TjOptimizerDayNewUser extends BaseModel
+{
+    protected $table = "tj_optimizer_day_new_users";
+    protected $fillable = ["id","date","user_id","puser_id","new_user_recharge_coin_num","miniprogram_id","miniprogram_name","miniprogram_play_name","miniprogram_type","new_user_num","new_user_recharge_num","new_user_recharge_vip_num","new_user_recharge_total","recharge_user_total","recharge_amount_total","updated_at","created_at"];
+}

+ 161 - 0
modules/Common/Services/Statistic/CompanyDayUser.php

@@ -0,0 +1,161 @@
+<?php
+/**
+ *
+ * @file:PromotionDayUser.php
+ * @Date: 2023/6/25
+ * @Time: 16:58
+ */
+
+
+namespace Modules\Common\Services\Statistic;
+
+use Illuminate\Support\Facades\DB;
+use Modules\Common\Models\TjCompanyDayNewUser;
+use Modules\Common\Models\TjOptimizerDayNewUser;
+use Modules\Common\Services\BaseService;
+
+class CompanyDayUser extends BaseService
+{
+    protected static $miniPrograms; // 小程序
+    protected static $newUserStatisc; // 新增用户
+    protected static $orderStatisc; // 充值统计
+    protected static $orderVipStatisc; // 充值会员统计
+    protected static $orderCoinStatisc; // 充值会员统计
+
+    /**
+     * 优化师用户统计
+     * name:companyDayUserStatistic
+     * @param $date
+     * date 2023/06/25 17:01
+     */
+    public static function companyDayUserStatistic($date)
+    {
+
+        self::getMiniProgram(); // 获取小程序
+        self::getStatisticOrders($date); // 进行订单统计
+        self::getStatisticNewUser($date);
+
+        //  从优化师维度出发统计
+        DB::table('users', 'u')
+            ->leftJoin('user_has_roles as  ur', 'ur.user_id', '=', 'u.id')
+            ->leftJoin('roles as r', 'r.id', '=', 'ur.role_id')
+            ->where('r.identify', 'company')
+            ->select("u.id as  user_id")->orderBy('u.id')
+            ->chunk(10, function ($items) use ($date) {
+                foreach ($items as $v) {
+                    self::getcompanyDayData($v->user_id, $date);
+                }
+            });
+    }
+
+    /**
+     *  优化师统计
+     * name: getcompanyDayData
+     * @param $accountId 账号id
+     * @param  $date 日期
+     * @return array|int[]
+     * date 2023/06/26 17:24
+     */
+    private static function getcompanyDayData($accountId, $date)
+    {
+
+        $userHasMin = DB::table('user_has_miniprograms')->where('uid', $accountId)->get();
+        $userHasMin = $userHasMin->pluck('miniprogram_id')->unique()->toArray();
+        if ($userHasMin) {
+            foreach ($userHasMin as $value) {
+                $userData = self::$newUserStatisc->where('user_id', $accountId)->where('miniprogram_id', $value)->first();
+                $order = self::$orderStatisc->where('user_id', $accountId)->where('miniprogram_id', $value)->first();
+                $vip = self::$orderVipStatisc->where('user_id', $accountId)->where('miniprogram_id', $value)->first();
+                $coin = self::$orderCoinStatisc->where('user_id', $accountId)->where('miniprogram_id', $value)->first();
+                $min = self::$miniPrograms->where('id', $value)->first();
+                $data = [
+                    'user_id' => $accountId,
+                    'miniprogram_id' => $value,
+                    'date' => $date,
+                    'new_user_num' => getProp($userData, 'new_user_num', 0),
+                    'new_user_recharge_num' => getProp($order, 'new_user_recharge_num', 0),
+                    'new_user_recharge_total' => getProp($order, 'new_user_recharge_total', 0),
+                    'new_user_recharge_vip_num' => getProp($vip, 'new_user_recharge_vip_num', 0),
+                    'new_user_recharge_coin_num' => getProp($coin, 'new_user_recharge_coin_num', 0),
+                    'miniprogram_name' => getProp($min, 'name', ''),
+                    'miniprogram_play_name' => getProp($min, 'play_name', ''),
+                    'miniprogram_type' => getProp($min, 'type', ''),
+                ];
+                $last = TjCompanyDayNewUser::where('user_id', $accountId)->where('miniprogram_id',$value)->where('date', "<", $date)->orderBy('date', "desc")->first();
+                if (!is_empty($last)) {
+                    $data['recharge_user_total'] = $last->recharge_user_total + $data['new_user_recharge_num'];
+                    $data['recharge_amount_total'] = $last->recharge_amount_total + $data['new_user_recharge_total'];
+                } else {
+                    $data['recharge_user_total'] = $data['new_user_recharge_num'];
+                    $data['recharge_amount_total'] = $data['new_user_recharge_total'];
+                }
+                TjCompanyDayNewUser::updateOrCreate(['user_id' => $data['user_id'], 'date' => $data['date'],'miniprogram_id' => $data['miniprogram_id']], $data);
+            }
+        }
+    }
+
+    /**
+     *   获取系统所有小程序
+     * name: getMiniProgram
+     * date 2023/06/26 17:21
+     */
+    private static function getMiniProgram()
+    {
+        self::$miniPrograms = DB::table('miniprogram')->get();
+    }
+
+    /**
+     *  统计当日订单
+     * name: getStatisticOrders
+     * @param $date
+     * date 2023/06/26 17:21
+     */
+    private static function getStatisticOrders($date)
+    {
+        $start = $date . " 00:00:00";
+        $end = $date . " 23:59:59";
+        self::$orderStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])
+            ->select(
+                'puser_id as user_id',
+                "miniprogram_id",
+                DB::raw("sum(if(status = 'unpaid', 0, price)) as  new_user_recharge_total"), // 单日新增用户充值金额
+                DB::raw("count(DISTINCT ranse_created_at,uid) as new_user_recharge_num")  // 当日新增用户充值人数
+            )->groupBy('puser_id', 'miniprogram_id')->get();
+        self::$orderVipStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])->whereNotIn("order_type",  ["COIN", "FIRST_COIN"])
+            ->select(
+                'puser_id as user_id',
+                "miniprogram_id",
+                DB::raw("COUNT(DISTINCT ranse_end_at,uid) as new_user_recharge_vip_num") // 会员充值人数
+            )->groupBy('puser_id', 'miniprogram_id')->get();
+        self::$orderCoinStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])->whereIn("order_type",  ["COIN", "FIRST_COIN"])
+            ->select(
+                'puser_id as user_id',
+                "miniprogram_id",
+                DB::raw("COUNT(DISTINCT ranse_end_at,uid) as new_user_recharge_coin_num") // 会员充值人数
+            )->groupBy('puser_id', 'miniprogram_id')->get();
+    }
+
+    /**
+     *  当日新用户统计
+     * name: getStatisticNewUser
+     * @param $date
+     * date 2023/06/26 17:21
+     */
+    private static function getStatisticNewUser($date)
+    {
+        self::$newUserStatisc = DB::table('user_ranse_record_all')->where('date', "=", $date)
+            ->select(
+                 'puser_id as user_id', 'miniprogram_id', 'miniprogram_type', 'date',
+                DB::raw('count(user_id) as new_user_num')
+            )->orderBy('puser_id')
+            ->groupBy('puser_id', 'miniprogram_id')->get();
+    }
+
+
+}

+ 170 - 0
modules/Common/Services/Statistic/OptimizerDayUser.php

@@ -0,0 +1,170 @@
+<?php
+/**
+ *
+ * @file:PromotionDayUser.php
+ * @Date: 2023/6/25
+ * @Time: 16:58
+ */
+
+
+namespace Modules\Common\Services\Statistic;
+
+use Illuminate\Support\Facades\DB;
+use Modules\Common\Models\TjOptimizerDayNewUser;
+use Modules\Common\Services\BaseService;
+
+class OptimizerDayUser extends BaseService
+{
+    protected static $miniPrograms; // 小程序
+    protected static $newUserStatisc; // 优化师
+    protected static $orderStatisc; // 充值统计
+    protected static $orderVipStatisc; // 充值会员统计
+    protected static $orderCoinStatisc; // 充值会员统计
+
+    /**
+     * 优化师用户统计
+     * name:optimizerDayUserStatistic
+     * @param $date
+     * date 2023/06/25 17:01
+     */
+    public static function optimizerDayUserStatistic($date)
+    {
+
+        self::getMiniProgram(); // 获取小程序
+        self::getStatisticOrders($date); // 进行订单统计
+        self::getStatisticNewUser($date);
+
+        //  从优化师维度出发统计
+        DB::table('users', 'u')
+            ->leftJoin('user_has_roles as  ur', 'ur.user_id', '=', 'u.id')
+            ->leftJoin('roles as r', 'r.id', '=', 'ur.role_id')
+            ->where('r.identify', 'optimizer')
+            ->select("u.id as  user_id", 'u.pid as  puser_id')->orderBy('u.id')
+            ->chunk(10, function ($items) use ($date) {
+                foreach ($items as $v) {
+                    self::getOptimizerDayData($v, $date);
+                }
+            });
+    }
+
+    /**
+     *  优化师统计
+     * name: getOptimizerDayData
+     * @param  $date 日期
+     * @param $data 账号
+     *  $data = [
+     *          'user_id' => 10, // 优化师id
+     *          'puser_id' => 2, // 公司账号id
+     *        ]
+     *
+     * @return array|int[]
+     * date 2023/06/26 17:24
+     */
+    private static function getOptimizerDayData($data, $date)
+    {
+        $userId = getProp($data, 'user_id');
+        $puserId = getProp($data, 'puser_id');
+        $userHasMin = DB::table('user_has_miniprograms')->where('uid', $userId)->get();
+        $userHasMin = $userHasMin->pluck('miniprogram_id')->unique()->toArray();
+        if ($userHasMin) {
+            foreach ($userHasMin as $value) {
+                $userData = self::$newUserStatisc->where('user_id', $userId)->where('miniprogram_id', $value)->first();
+                $order = self::$orderStatisc->where('user_id', $userId)->where('miniprogram_id', $value)->first();
+                $vip = self::$orderVipStatisc->where('user_id', $userId)->where('miniprogram_id', $value)->first();
+                $coin = self::$orderCoinStatisc->where('user_id', $userId)->where('miniprogram_id', $value)->first();
+                $min = self::$miniPrograms->where('id', $value)->first();
+                $data = [
+                    "user_id" => $userId,
+                    'puser_id' => $puserId,
+                    'miniprogram_id' => $value,
+                    'date' => $date,
+                    'new_user_num' => getProp($userData, 'new_user_num', 0),
+                    'new_user_recharge_num' => getProp($order, 'new_user_recharge_num', 0),
+                    'new_user_recharge_total' => getProp($order, 'new_user_recharge_total', 0),
+                    'new_user_recharge_vip_num' => getProp($vip, 'new_user_recharge_vip_num', 0),
+                    'new_user_recharge_coin_num' => getProp($coin, 'new_user_recharge_coin_num', 0),
+                    'miniprogram_name' => getProp($min, 'name', ''),
+                    'miniprogram_play_name' => getProp($min, 'play_name', ''),
+                    'miniprogram_type' => getProp($min, 'type', ''),
+                ];
+                $last = TjOptimizerDayNewUser::where('user_id', $userId)->where('miniprogram_id',$value)->where('puser_id', $puserId)->where('date', "<", $date)->orderBy('date', "desc")->first();
+                if (!is_empty($last)) {
+                    $data['recharge_user_total'] = $last->recharge_user_total + $data['new_user_recharge_num'];
+                    $data['recharge_amount_total'] = $last->recharge_amount_total + $data['new_user_recharge_total'];
+                } else {
+                    $data['recharge_user_total'] = $data['new_user_recharge_num'];
+                    $data['recharge_amount_total'] = $data['new_user_recharge_total'];
+                }
+                TjOptimizerDayNewUser::updateOrCreate(['user_id' => $data['user_id'], 'puser_id' => $data['puser_id'], 'date' => $data['date'],'miniprogram_id' => $data['miniprogram_id']], $data);
+            }
+        }
+    }
+
+    /**
+     *   获取系统所有小程序
+     * name: getMiniProgram
+     * date 2023/06/26 17:21
+     */
+    private static function getMiniProgram()
+    {
+        self::$miniPrograms = DB::table('miniprogram')->get();
+    }
+
+    /**
+     *  统计当日订单
+     * name: getStatisticOrders
+     * @param $date
+     * date 2023/06/26 17:21
+     */
+    private static function getStatisticOrders($date)
+    {
+        $start = $date . " 00:00:00";
+        $end = $date . " 23:59:59";
+        self::$orderStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])
+            ->select(
+                "user_id",
+                'puser_id',
+                "miniprogram_id",
+                DB::raw("sum(if(status = 'unpaid', 0, price)) as  new_user_recharge_total"), // 单日新增用户充值金额
+                DB::raw("count(DISTINCT ranse_created_at,uid) as new_user_recharge_num")  // 当日新增用户充值人数
+            )->groupBy('user_id', 'miniprogram_id')->get();
+        self::$orderVipStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])->whereNotIn("order_type", ["COIN", "FIRST_COIN"])
+            ->select(
+                "user_id",
+                'puser_id',
+                "miniprogram_id",
+                DB::raw("COUNT(DISTINCT ranse_end_at,uid) as new_user_recharge_vip_num") // 会员充值人数
+            )->groupBy('user_id', 'miniprogram_id')->get();
+        self::$orderCoinStatisc = DB::table('orders')->where('status', "<>", 'UNPAID')
+            ->whereBetween("created_at", [$start, $end])
+            ->whereBetween('ranse_created_at', [$start, $end])->whereIn("order_type", ["COIN", "FIRST_COIN"])
+            ->select(
+                "user_id",
+                'puser_id',
+                "miniprogram_id",
+                DB::raw("COUNT(DISTINCT ranse_end_at,uid) as new_user_recharge_coin_num") // 普通充值人数
+            )->groupBy('user_id', 'miniprogram_id')->get();
+    }
+
+    /**
+     *  当日新用户统计
+     * name: getStatisticNewUser
+     * @param $date
+     * date 2023/06/26 17:21
+     */
+    private static function getStatisticNewUser($date)
+    {
+        self::$newUserStatisc = DB::table('user_ranse_record_all')->where('date', "=", $date)
+            ->select(
+                "user_id", 'puser_id', 'miniprogram_id', 'miniprogram_type', 'date',
+                DB::raw('count(user_id) as new_user_num')
+            )->orderBy('user_id')
+            ->groupBy('user_id', 'miniprogram_id')->get();
+    }
+
+
+}

+ 58 - 4
modules/Statistic/Http/Controllers/UserStatisticsController.php

@@ -13,6 +13,7 @@ use Catch\Base\CatchController;
 use Catch\Exceptions\FailedException;
 use Illuminate\Http\Request;
 
+use Modules\Common\Services\Statistic\OptimizerDayUser;
 use Modules\Statistic\Services\UserStatisticsService;
 use Modules\User\Http\Controllers\UserTrait;
 
@@ -27,10 +28,26 @@ class UserStatisticsController extends CatchController
      */
     public function todayData(Request $request)
     {
-        $miniProgramId = $request->input('miniprogram_id',0);
-        if ($miniProgramId < 1){
-            throw new FailedException("参数错误,小程序id必传");
+        $userContext = $this->getUserContext(null);
+        $type = 1;
+        if( $userContext['loginUserRoles']->contains('company')){
+            $type = 2;
+        }else if ($userContext['loginUserRoles']->contains('optimizer')){
+            $type = 3;
         }
+        $uid = $this->getLoginUserId();
+        return UserStatisticsService::getTodayData($uid,$type);
+    }
+
+    /**
+     *  历史统计
+     * name: stats
+     * @param Request $request
+     * date 2023/06/25 14:24
+     */
+    public function stats(Request $request)
+    {
+        $miniProgramId = $request->input('miniprogram_id',0);
         $userContext = $this->getUserContext(null);
         $type = 1;
         if( $userContext['loginUserRoles']->contains('company')){
@@ -39,8 +56,45 @@ class UserStatisticsController extends CatchController
             $type = 3;
         }
         $uid = $this->getLoginUserId();
-        return UserStatisticsService::getTodayData($uid,$miniProgramId,$type);
+        return UserStatisticsService::historyStats($uid,$type);
     }
 
+    /**
+     *   列表查询
+     * name: list
+     * @param Request $request
+     * date 2023/06/25 14:24
+     */
+    public function list(Request $request){
+        $param = $request->all();
+        $userContext = $this->getUserContext(null);
+        if (getProp($param, 'puser_id')) {
+            $param['puser_id'] = $param['puser_id'];
+        }
+        if (getProp($param, 'user_id')) {
+            $param['user_id'] = $param['user_id'];
+        }
+        // 公司账户处理
+        if ($userContext['loginUserRoles']->contains('company')) {
+            $param['puser_id'] = $userContext['operateUser']->id;
+        }
 
+        // 投手处理
+        if ($userContext['loginUserRoles']->contains('optimizer')) {
+            $param['user_id'] = $userContext['operateUser']->id;
+            $param['puser_id'] = $userContext['operateUser']->pid;
+        }
+        if (!getProp($param,'end_at')){
+            $param['end_at'] = date('Y-m-d');
+        }else{
+            $param['end_at'] = date('Y-m-d',strtotime($param['end_at']));
+        }
+        if (!getProp($param,'start_at')){
+            // 默认最近7天
+           $param['start_at'] = date('Y-m-d',strtotime($param['end_at'])-86400*7);
+        }else{
+            $param['start_at'] = date('Y-m-d',strtotime($param['start_at']));
+        }
+       return UserStatisticsService::list($param);
+    }
 }

+ 170 - 20
modules/Statistic/Services/UserStatisticsService.php

@@ -11,36 +11,38 @@ namespace Modules\Statistic\Services;
 
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Redis;
+use Modules\Common\Models\TjOptimizerDayNewUser;
 use Modules\Common\Services\BaseService;
+use Modules\Common\Services\Statistic\CompanyDayUser;
+use Modules\Common\Services\Statistic\OptimizerDayUser;
 
 class UserStatisticsService extends BaseService
 {
 
-    // 日期:小程序id
-    protected const PROMOTION_STATISTIC_RECORD_REDIS_KEY = 'statistic:miniprogram:users_recode:%s:%s';
+    // key 日期:
+    protected const PROMOTION_STATISTIC_RECORD_REDIS_KEY = 'statistic:miniprogram:users_recode:%s';
     protected const NEW_USER_NUM = 'new_user_num_%s'; // 当日新增用户数
     protected const NEW_USER_RECHARGE_NUM = "new_user_recharge_num_%s"; // 当日新增户充值人数
     protected const NEW_USER_RECHARGE_TOTAL = "new_user_recharge_total_%s"; // 当日新增户充值金额
+    protected const RANSE_NEW_USER_COUNT = "promotion:newUserCount:%s"; // 推广链接新用户统计
 
     /**
      *
      * name: getTodayData
      * @param int $accountId 账号id
-     * @param int $miniProgramId 小程序id
      * @param int $type 账号类型 1 其他 2 投放公司 3 优化师
      * date 2023/06/20 10:20
+     * @return array
      */
-    public static function getTodayData($accountId, $miniProgramId, $type = 1)
+    public static function getTodayData($accountId, $type = 1)
     {
         $date = date("Y-m-d");
-        $key = sprintf(self::PROMOTION_STATISTIC_RECORD_REDIS_KEY, $date, $miniProgramId);
+        $key = sprintf(self::PROMOTION_STATISTIC_RECORD_REDIS_KEY, $date);
         $new_user_recharge_total = self::getValue($key, sprintf(self::NEW_USER_RECHARGE_TOTAL, $accountId)); // 当日新增用户充值总额
         $new_user_recharge_num = self::getValue($key, sprintf(self::NEW_USER_RECHARGE_NUM, $accountId)); // 当日新增用户充值人数
         $new_user_num = self::getValue($key, sprintf(self::NEW_USER_NUM, $accountId)); // 当日新增用户人数
-        [$recharge_coin_num, $recharge_vip_num] = self::getRechargeUserNum($accountId, $miniProgramId, $type);
+        [$recharge_coin_num, $recharge_vip_num] = self::getRechargeUserNum($accountId, $type);
         $data = [
-            'key' => $key,
-            'account_id' =>  $accountId,
             'date' => $date,
             'new_user_recharge_total' => $new_user_recharge_total ?: 0,
             'new_user_recharge_num' => $new_user_recharge_num ?: 0,
@@ -50,13 +52,13 @@ class UserStatisticsService extends BaseService
         ];
 
         if ($new_user_num > 0 && $new_user_recharge_num > 0) {
-            $data['recharge_rate'] = sprintf('%.2f%', ($new_user_recharge_num / $new_user_num) * 100);
+            $data['recharge_rate'] = sprintf("%.2f%s", ($new_user_recharge_num / $new_user_num) * 100, "%");
         } else {
             $data['recharge_rate'] = 0;
             $data['recharge_mean'] = 0;
         }
         if ($new_user_recharge_total > 0 || $new_user_recharge_num > 0) {
-            $data['recharge_mean'] = sprintf('%.2f', ($new_user_recharge_total / $new_user_recharge_num));
+            $data['recharge_mean'] = sprintf('%.2f%s', ($new_user_recharge_total / $new_user_recharge_num), "%");
         } else {
             $data['recharge_mean'] = 0;
         }
@@ -64,13 +66,28 @@ class UserStatisticsService extends BaseService
         return $data;
     }
 
-    // 获取redis值
+    /**
+     * 获取redis值
+     * name: getValue
+     * @param $key
+     * @param $field
+     * @return mixed
+     * date 2023/06/25 15:57
+     */
     protected static function getValue($key, $field)
     {
         return Redis::hget($key, $field);
     }
 
-    // 保存redis的值
+
+    /**
+     * 保存redis的值
+     * name: setValue
+     * @param $key
+     * @param $field
+     * @param $value
+     * date 2023/06/25 15:57
+     */
     protected static function setValue($key, $field, $value)
     {
         Redis::hset($key, $field, $value);
@@ -84,33 +101,29 @@ class UserStatisticsService extends BaseService
      * @param mixed $type 账号类型 2 投放公司 3 优化师
      * date 2023/06/20 10:18
      */
-    private static function getRechargeUserNum($accountId, $miniProgramId, mixed $type): array
+    private static function getRechargeUserNum($accountId, mixed $type): array
     {
         $start = date("Y-m-d") . " 00:00:00";
         $end = date("Y-m-d") . " 23:59:59";
         if ($type == 2) {
             // 投放公司
             $recharge_coin_num = DB::table('orders')->where('status', "<>", 'UNPAID')
-                ->where('miniprogram_id', $miniProgramId)
                 ->where('puser_id', $accountId)->whereBetween("created_at", [$start, $end])
                 ->whereBetween('ranse_created_at', [$start, $end])
                 ->where('order_type', 'COIN')->groupBy('uid', 'ranse_created_at')->count();
             $recharge_vip_num = DB::table('orders')->where('status', "<>", 'UNPAID')
-                ->where('miniprogram_id', $miniProgramId)
-                ->where('puser_id', $accountId)->whereBetween("created_at",[ $start, $end])
+                ->where('puser_id', $accountId)->whereBetween("created_at", [$start, $end])
                 ->whereBetween('ranse_created_at', [$start, $end])
                 ->where('order_type', '<>', 'COIN')->groupBy('uid', 'ranse_created_at')->count();
         } elseif ($type == 3) {
             // 优化师
             $recharge_coin_num = DB::table('orders')->where('status', "<>", 'UNPAID')
-                ->where('miniprogram_id', $miniProgramId)
                 ->where('user_id', $accountId)->whereBetween("created_at", [$start, $end])
                 ->whereBetween('ranse_created_at', [$start, $end])
                 ->where('order_type', 'COIN')->groupBy('uid', 'ranse_created_at')->count();
             $recharge_vip_num = DB::table('orders')->where('status', "<>", 'UNPAID')
-                ->where('miniprogram_id', $miniProgramId)
-                ->where('user_id', $accountId)->whereBetween("created_at",[$start, $end])
-                ->whereBetween('ranse_created_at',[ $start, $end])
+                ->where('user_id', $accountId)->whereBetween("created_at", [$start, $end])
+                ->whereBetween('ranse_created_at', [$start, $end])
                 ->where('order_type', '<>', 'COIN')->groupBy('uid', 'ranse_created_at')->count();
         } else {
             // 其他暂不统计
@@ -119,4 +132,141 @@ class UserStatisticsService extends BaseService
         }
         return [$recharge_coin_num, $recharge_vip_num];
     }
+
+    /**
+     *
+     * name: getTodayData
+     * @param int $accountId 账号id
+     * @param mixed $type 账号类型 1 其他 2 投放公司 3 优化师
+     */
+    public static function historyStats(int $accountId, $type)
+    {
+        print_sql();
+        $month = self::getStaticsData($accountId,date('Y-m-01'), date('Y-m-d', strtotime('yesterday')), $type);
+        $lastMonth = self::getStaticsData($accountId,date('Y-m-01',strtotime(date('Y-m-01'))-10), date('Y-m-d',strtotime(date('Y-m-01'))-10), $type);
+        $history = self::getHistoryData($accountId,$type);
+        return ['month' => $month,'lastMonth' => $lastMonth,'history' => $history];
+    }
+
+    /**
+     *   历史汇总
+     * name: getMonthData
+     * @param int $accountId 账号
+     * @param mixed $type 角色类型 账号类型 1 其他 2 投放公司 3 优化师
+     * @param  mixed $minId 小程序id
+     * date 2023/06/27 11:19
+     */
+    protected static function getHistoryData($accountId, $type, $minId = 0)
+    {
+        $date = date('Y-m-d', strtotime('yesterday'));
+        $sql = TjOptimizerDayNewUser::where('date',$date);
+        if ($type == 2) {
+            $sql->where('puser_id', $accountId);
+        } elseif ($type == 3) {
+            $sql->where('puser_id', $accountId);
+        }
+        if ($minId){
+            $sql->where('miniprogram_id',$minId);
+        }
+        $info = $sql->select(
+            DB::raw("sum(recharge_amount_total) as recharge_amount_total"), // 总充金额
+            DB::raw("sum(recharge_user_total) as recharge_user_total"), // 累计充值人数
+        )->first();
+
+        return [
+            'recharge_amount_total' => $info->recharge_amount_total?:0,
+            'recharge_user_total' => $info->recharge_user_total?: 0,
+        ];
+    }
+
+    /**
+     *    日期范围的统计
+     * name: getMonthData
+     * @param int $accountId 账号
+     * @param mixed $type 角色类型 账号类型 1 其他 2 投放公司 3 优化师
+     * @param  mixed $minId 小程序id
+     * date 2023/06/27 11:19
+     */
+    private static function getStaticsData($accountId, $start, $end,$type,$minId = 0)
+    {
+        $sql = TjOptimizerDayNewUser::where('date', '>=', $start)->where("date", "<=", $end);
+        if ($type == 2) {
+            $sql->where('puser_id', $accountId);
+        } elseif ($type == 3) {
+            $sql->where('puser_id', $accountId);
+        }
+        if ($minId){
+            $sql->where('miniprogram_id',$minId);
+        }
+        $info = $sql->select(
+            DB::raw("sum(new_user_recharge_total) as new_user_recharge_total"), // 充值人数
+            DB::raw("sum(new_user_num) as new_user_num"), // 新增用户人数
+            DB::raw("sum(new_user_recharge_num) as new_user_recharge_num"), // 充值人数
+            DB::raw("sum(new_user_recharge_vip_num) as new_user_recharge_vip_num"), // VIP充值人数
+            DB::raw("sum(new_user_recharge_coin_num) as new_user_recharge_coin_num") // 普通充值人数
+        )->first();
+        return [
+            'new_user_recharge_total' => $info->new_user_recharge_total?:0,
+            'new_user_num' => $info->new_user_num?: 0,
+            'new_user_recharge_num' => $info->new_user_recharge_num?:0,
+            'new_user_recharge_vip_num' => $info->new_user_recharge_vip_num?: 0,
+            'new_user_recharge_coin_num' => $info->new_user_recharge_coin_num ?:0,
+        ];
+
+    }
+
+
+
+    /**
+     * 统计列表
+     */
+    public static function list(array $param)
+    {
+        $sql = self::getQuerySql($param)->select("tj_day_new_users.*", 'users.username')->orderBy('date', 'desc')->orderBy('id', 'desc');
+        $isAll = getProp($param, 'is_all');
+        if ($isAll) {
+            $list = $sql->get();
+        } else {
+            $list = $sql->paginate(getProp($param, 'limit', 15));
+        }
+        if ($list->isEmpty()) {
+            return $list;
+        }
+        $companyIds = $list->pluck('puser_id')->unique()->toArray();
+
+        $companys = DB::table('users')->whereIn('id', $companyIds)->get();
+
+        foreach ($list as $value) {
+            // 充值率
+            $value->recharge_rate = $value->new_user_recharge_num > 0 && $value->new_user_num > 0 ? sprintf("%.2f%s", $value->new_user_recharge_num / $value->new_user_num, "%") : 0;
+            // 人均充值
+            $value->recharge_mean = $value->new_user_recharge_num > 0 && $value->new_user_recharge_total > 0 ? sprintf("%.2f%s", $value->new_user_recharge_total / $value->new_user_recharge_num, "%") : 0;
+            $value->company_name = $companys->where('id', $value->puser_id)->value('username');
+        }
+        return $list;
+    }
+
+
+    private static function getQuerySql(array $param)
+    {
+        $sql = TjOptimizerDayNewUser::query()->leftJoin('users', 'users.id', "=", 'tj_day_new_users.user_id');
+        if (getProp($param, 'start_at')) {
+            $sql->where('tj_day_new_users.date', ">=", $param['start_at']);
+        }
+        if (getProp($param, 'end_at')) {
+            $sql->where('tj_day_new_users.date', "<=", $param['end_at']);
+        }
+        if (getProp($param, 'user_id')) {
+            $sql->where('tj_day_new_users.user_id', $param['user_id']);
+        }
+        if (getProp($param, 'puser_id')) {
+            $sql->where('tj_day_new_users.puser_id', $param['puser_id']);
+        }
+        if (getProp($param, 'miniprogram_id')) {
+            $sql->where('tj_day_new_users.miniprogram_id', $param['miniprogram_id']);
+        }
+        return $sql;
+    }
+
+
 }

+ 5 - 0
modules/Statistic/routes/route.php

@@ -7,6 +7,11 @@ Route::prefix('statistic')->group(function(){
     //next
     // 用户统计
     Route::prefix('users')->group(function (){
+        // 今天数据统计
         Route::any('today',[UserStatisticsController::class,'todayData']);
+        // 历史充值统计
+        Route::any('stats',[UserStatisticsController::class,'stats']);
+        // 投手日充值列表
+        Route::any('list',[UserStatisticsController::class,'list']);
     });
 });