<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 易而优团队 by 陈风任 <491085389@qq.com>
 * Date: 2019-11-21
 */

namespace app\admin\controller;

use think\Db;
use think\Config;

// 数据统计
class Statistics extends Base
{

    private $UsersConfigData = [];

    public function _initialize()
    {
        parent::_initialize();

        // 会员中心配置信息
        $this->UsersConfigData = getUsersConfigData('all');
        $this->assign('userConfig', $this->UsersConfigData);
    }

    /**
     * 数据表列表
     */
    public function index()
    {
        // 近七日成交量成交额折线图数据
        $LineChartData = $this->GetLineChartData();
        $this->assign('DealNum', $LineChartData['DealNum']);
        $this->assign('DealAmount', $LineChartData['DealAmount']);

        // 起始时间
        $StartTime = $this->GetTime(6);
        $EndTime = getTime();
        $this->assign('StartTime', $StartTime);
        $this->assign('EndTime', $EndTime);

        // 数据统计
        $CycletData = $this->GetTimeCycletData($StartTime, $EndTime);
        $this->assign('CycletData', $CycletData);

        // 商品销售榜
        $OrderSalesList = $this->GetOrderSalesList();
        $this->assign('OrderSalesList', $OrderSalesList);

        return $this->fetch();
    }

    // 商品销售榜
    private function GetOrderSalesList()
    {
        // 查询销量最高的前十个商品
        $field_0 = 'aid, title, sales_num, click, status';
        $where_0 = [
            'typeid' => ['IN', Db::name('arctype')->where('current_channel', 2)->column('id')],
            'channel' => 2,
        ];
        $Archives = Db::name('archives')->field($field_0)->where($where_0)->limit(10)->order('sales_num desc')->select();

        // 统计单个商品销售总额
        $where_1 = [
            'a.product_id' => ['IN', get_arr_column($Archives, 'aid')],
            'b.order_status' => ['IN', [1, 2, 3]],
        ];
        $Price = Db::name('shop_order_details')->alias('a')
            ->field('a.product_id, sum(a.product_price*a.num) as price, count(a.details_id) as sales_num')
            ->join('__SHOP_ORDER__ b', 'a.order_id = b.order_id', 'LEFT')
            ->where($where_1)
            ->group('product_id')
            ->select();

        // 数据处理并返回
        $Price = convert_arr_key($Price, 'product_id');
        $Archives = convert_arr_key($Archives, 'aid');
        $ArchivesNew = get_archives_data($Archives, 'aid');
        foreach ($Archives as $key => $value) {
            $Archives[$key]['arcurl'] = get_arcurl($ArchivesNew[$key]);
            $Archives[$key]['title'] = @msubstr($value['title'], 0, 25, '...');
            $Archives[$key]['sales_amount'] = !empty($Price[$key]['price']) ? $Price[$key]['price'] : 0;
            $Archives[$key]['sales_num'] = !empty($Price[$key]['sales_num']) ? $Price[$key]['sales_num'] : 0;
        }
        return $Archives;
    }

    // 获取时间周期内的指定数据
    public function GetTimeCycletData($Start = null, $End = null)
    {
        $param = input('param.');
        if (!empty($param['Year']) && 0 != $param['Year']) {
            $param['Start'] = strtotime("-0 year -{$param['Year']} month -0 day");
            $param['End'] = getTime();
        } else {
            if (empty($Start) || empty($End)) {
                $param['Start'] = strtotime($param['StartNew']);
                $param['End'] = strtotime($param['EndNew'] . ' 23:59:59');
            } else {
                $param = [
                    'Start' => $Start,
                    'End' => $End,
                ];
            }
        }

        // 会员查询条件
        $Uwhere = [
            'reg_time' => ['between', [$param['Start'], $param['End']]]
        ];

        // 商品查询条件
        $Awhere = [
            'typeid' => ['IN', Db::name('arctype')->where('current_channel', 2)->column('id')],
            'channel' => 2,
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];

        // 商品查询条件
        $Swhere = [
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];

        // 订单查询条件
        $Owhere = [
            'order_status' => ['IN', [1, 2, 3]],
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];
        // 查询订单数据
        $Result = $this->GetTimeWhereData($Owhere);

        // 充值查询条件
        $Mwhere = [
            'cause' => Config::get('global.pay_cause_type_arr')[1],
            'cause_type' => 1,
            'status' => 3,
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];

        $Return = [
            // 会员人数
            'UsersNum' => Db::name('users')->where($Uwhere)->count(),
            // 付款订单数
            'PayOrderNum' => $Result['deal_num'],
            // 订单销售额
            'OrderSales' => $Result['deal_amount'],
            // 商品数
            'ProductNum' => Db::name('archives')->where($Awhere)->count(),
            // 消费人数
            'OrderUsersNum' => Db::name('shop_order')->where($Swhere)->group('users_id')->count(),
            // 充值金额
            'UsersRecharge' => Db::name('users_money')->where($Mwhere)->sum('money'),
            // 返回查询时间
            'Start' => date("Y-m-d H:i:s", $param['Start']),
            'End' => date("Y-m-d H:i:s", $param['End'])
        ];

        if (IS_AJAX_POST) {
            $this->success('查询成功！', null, $Return);
        } else {
            return $Return;
        }
    }

    // 近七日成交量成交额折线图数据    
    private function GetLineChartData()
    {
        $now_day = strtotime(date("Y-m-d"), time());
        $dataNum = $dataAmount = [];

        for ($i = 0; $i < 7; $i++) {
            $time = $now_day - $i * 86400;
            //成交量
            $dataNum[$i] = Db::name('statistics_data')->where(['type' => 2, 'date' => $time])->value('num');
            //成交额
            $dataAmount[$i] = Db::name('statistics_data')->where(['type' => 3, 'date' => $time])->value('total');
        }
        $dataNum = array_reverse($dataNum);
        $dataAmount = array_reverse($dataAmount);
        for ($i = 0; $i < 7; $i++) {
            if (empty($dataNum[$i])) {
                $dataNum[$i] = 0;
                $dataAmount[$i] = 0;
            }
        }

        $Return = [
            'DealAmount' => $dataAmount,
            'DealNum' => $dataNum
        ];

        return $Return;
    }

    // 获取指定日期下的数据
    private function GetTimeWhereData($where = [])
    {
        $field = 'sum(order_total_amount+shipping_fee) as deal_amount, count(users_id) as deal_num';
        $Return = Db::name('shop_order')->field($field)->where($where)->select();

        $Return[0]['deal_amount'] = $Return[0]['deal_amount'] ? $Return[0]['deal_amount'] : 0;
        $Return[0]['deal_num'] = $Return[0]['deal_num'] ? $Return[0]['deal_num'] : 0;
        return $Return[0];
    }

    // 获取指定日期时间戳
    private function GetTime($num = null)
    {
        $time = strtotime(date("Y-m-d", strtotime("-{$num} day")));
        return $time;
    }

    //会员数据统计
    public function users_index()
    {
        // 近七日新增用户折线图数据
        $LineChartData = $this->GetNewUsersData();
        $this->assign('NewUsersNum', $LineChartData);

        // 用户消费榜
        $UserConsumption = $this->GetUserConsumption();
        $this->assign('UserConsumption', $UserConsumption);

        // 起始时间
        $StartTime = $this->GetTime(6);
        $EndTime = getTime();
        $this->assign('StartTime', $StartTime);
        $this->assign('EndTime', $EndTime);

        // 数据统计
        $CycletData = $this->GetTimeUsersData($StartTime, $EndTime);
        $this->assign('totalData', $CycletData);

        return $this->fetch();
    }

    // 获取时间周期内的会员指定数据
    public function GetTimeUsersData($Start = null, $End = null)
    {
        $param = input('param.');
        if (!empty($param['Year']) && 0 != $param['Year']) {
            $param['Start'] = strtotime("-0 year -{$param['Year']} month -0 day");
            $param['End'] = getTime();
        } else {
            if (empty($Start) || empty($End)) {
                $param['Start'] = strtotime($param['StartNew']);
                $param['End'] = strtotime($param['EndNew'] . ' 23:59:59');
            } else {
                $param = [
                    'Start' => $Start,
                    'End' => $End,
                ];
            }
        }

        // 会员查询条件
        $users_where = [
            'reg_time' => ['between', [$param['Start'], $param['End']]],
            'is_real' => 1
        ];

        // 订单查询条件
        $order_where = [
            'order_status' => ['IN', [1, 2, 3]],
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];
        // 充值订单查询条件
        $recharge_where = [
            'cause_type' => 1,
            'status' => 3,
            'add_time' => ['between', [$param['Start'], $param['End']]]
        ];
        // 优惠券领取查询条件
        $coupon_where = [
            'get_time' => ['between', [$param['Start'], $param['End']]]
        ];

        $Return['Start'] = date("Y-m-d H:i:s", $param['Start']);
        $Return['End'] = date("Y-m-d H:i:s", $param['End']);
        $Return['NewUsers'] = Db::name('users')->where($users_where)->count();
        $Return['OrderUsers'] = Db::name('shop_order')->where($order_where)->group('users_id')->count();
        $Return['RechargeUsers'] = Db::name('users_money')->where($recharge_where)->group('users_id')->count();
        $Return['CouponUsers'] = Db::name('shop_coupon_use')->where($coupon_where)->group('users_id')->count();

        if (IS_AJAX_POST) {
            $this->success('查询成功！', null, $Return);
        } else {
            return $Return;
        }
    }

    // 用户消费榜
    private function GetUserConsumption()
    {
        $where = [
            'order_status' => ['IN', [1, 2, 3]]
        ];
        $Return = Db::name('shop_order')->field('users_id, sum(order_total_amount+shipping_fee) as amount,count(order_id) as count')
            ->where($where)
            ->group('users_id')
            ->order('amount desc,users_id asc')
            ->select();

        $Return = convert_arr_key($Return, 'users_id');

        $UsersData = Db::name('users')
            ->alias('a')
            ->where('a.is_real',1)
            ->field('a.users_id, a.username, a.nickname,b.level_name')
            ->join('users_level b', 'a.level = b.level_id')
            ->select();
        foreach ($UsersData as $key => $value) {
            $UsersData[$key]['amount'] = !empty($Return[$value['users_id']]['amount']) ? $Return[$value['users_id']]['amount'] : 0;
            $UsersData[$key]['count'] = !empty($Return[$value['users_id']]['count']) ? $Return[$value['users_id']]['count'] : 0;
            $UsersData[$key]['nickname'] = !empty($UsersData[$key]['nickname']) ? $UsersData[$key]['nickname'] : $UsersData[$key]['username'];
        }

        // 以消费金额排序
        array_multisort(get_arr_column($UsersData, 'amount'), SORT_DESC, $UsersData);
        // 读取前十数据
        $UsersData = array_slice($UsersData, 0, 10);

        return $UsersData;
    }

    // 近七日新增会员数
    private function GetNewUsersData()
    {
        $where['is_del'] = 0;
        $where['is_real'] = 1;
        // 六天前
        $start = $this->GetTime(6);
        $end = $this->GetTime(6) + 86399;
        $where['reg_time'] = ['between', [$start, $end]];
        $Return[0] = Db::name('users')->where($where)->count('users_id');
        // 五天前
        $start = $this->GetTime(5);
        $end = $this->GetTime(5) + 86399;
        $where['reg_time'] = ['between', [$start, $end]];
        $Return[1] = Db::name('users')->where($where)->count('users_id');
        // 四天前
        $start = $this->GetTime(4);
        $end = $this->GetTime(4) + 86399;
        $where['reg_time'] = ['between', [$start, $end]];
        $Return[2] = Db::name('users')->where($where)->count('users_id');
        // 三天前
        $start = $this->GetTime(3);
        $end = $this->GetTime(3) + 86399;
        $where['reg_time'] = ['between', [$start, $end]];
        $Return[3] = Db::name('users')->where($where)->count('users_id');
        // 前天
        $start = $this->GetTime(2);
        $end = $this->GetTime(2) + 86399;
        $where['reg_time'] = ['between', [$start, $end]];
        $Return[4] = Db::name('users')->where($where)->count('users_id');
        // 昨天
        $Return[5] = Db::name('users')->whereTime('reg_time', 'yesterday')->count('users_id');

        // 当天
        $Return[6] = Db::name('users')->whereTime('reg_time', 'today')->count('users_id');

        return $Return;
    }
}