<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\store\logic;


use app\common\enum\PayEnum;
use app\common\logic\BaseLogic;
use app\common\logic\store_order\StoreOrderLogic;
use app\common\model\order\Cart;
use app\common\model\store_cash_finance_flow\StoreCashFinanceFlow;
use app\common\model\store_order\StoreOrder;
use app\common\model\store_order_cart_info\StoreOrderCartInfo;
use app\common\model\store_visit\StoreVisit;
use app\common\service\ConfigService;
use app\common\service\FileService;


/**
 * 工作台
 * Class WorkbenchLogic
 * @package app\store\logic
 */
class WorkbenchLogic extends BaseLogic
{

    public static function index($params)
    {
        $data = [];
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];
        $endTime = date('Y-m-d', strtotime($endTime) + 86400);
        $dateDiff = (new \DateTime($endTime))->diff(new \DateTime($startTime));
        $orderLogic = new StoreOrderLogic();
        //订单总金额
        $data['order_amount'] = $orderLogic->storeOrderSumByDate($params['store_id'], $startTime, $endTime);
        //余额支付总金额
        $data['balance_amount'] = $orderLogic->storeOrderSumByDate($params['store_id'], $startTime, $endTime, ['pay_type' => PayEnum::BALANCE_PAY]);
        //线下收银总金额
        $data['cashier_amount'] = $orderLogic->storeOrderSumByDate($params['store_id'], $startTime, $endTime, ['shipping_type' => 3]);
        //现金收银总金额
        $data['cash_amount'] = StoreCashFinanceFlow::where('store_id', $params['store_id'])->whereBetweenTime('create_time', $startTime, $endTime)->sum('cash_price');
        //核销订单金额
        $data['verify_amount'] = $orderLogic->storeOrderSumByDate($params['store_id'], $startTime, $endTime, ['shipping_type' => 2]);
        //门店收益金额
        $data['income_amount'] = $orderLogic->storeOrderSumByDate($params['store_id'], $startTime, $endTime, [], 'profit');
        //门店成交用户数
        $data['user_number'] = StoreOrder::where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group('uid')
            ->count();
        if ($dateDiff->days == 1) {
            $group = 'HOUR(pay_time)';
            $i = 0;
            while ($i < 24) {
                $timeRange[] = date('H', strtotime("+$i hours", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%H") as pay_time,sum(pay_price) as pay_price';
        } elseif ($dateDiff->days <= 31) {
            $group = 'DAY(pay_time)';
            $i = 0;
            while ($i < $dateDiff->days) {
                $timeRange[] = date('m-d', strtotime("+$i days", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%m-%d") as pay_time,sum(pay_price) as pay_price';
        } else {
            $group = 'MONTH(pay_time)';
            $i = 0;
            $month = 0;
            if ($dateDiff->y > 0) {
                $month = $dateDiff->y * 12;
            }
            if ($dateDiff->m > 0) {
                $month += $dateDiff->m;
            }
            if ($dateDiff->d > 0) {
                $month += 1;
            }
            while ($i < $month) {
                $timeRange[] = date('Y-m', strtotime("+$i months", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%Y-%m") as pay_time,sum(pay_price) as pay_price';
        }
        $orderList = StoreOrder::field($field)
            ->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group($group)
            ->select()
            ->toArray();
        $userList = StoreOrder::field($field . ',count(uid) as user_num')
            ->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group($group . ',uid')
            ->select()
            ->toArray();
        $orderList = reset_index($orderList, 'pay_time');
        $userList = reset_index($userList, 'pay_time');
        $orderListTmp = [];
        $userListTmp = [];
        $range = [];
        foreach ($timeRange as $item) {
            $range[] = $item;
            if (!isset($orderList[$item])) {
                $orderListTmp[$item] = 0;
            } else {
                $orderListTmp[$item] = $orderList[$item]['pay_price'];
            }
            if (!isset($userList[$item])) {
                $userListTmp[$item] = 0;
            } else {
                $userListTmp[$item] = $userList[$item]['user_num'];
            }
        }
        $data['statistics'] = [
            'range' => $range,
            'data' => [
                'order_amount' => array_values($orderListTmp),
                'user_number' => array_values($userListTmp)
            ]
        ];
        $data['order_list'] = StoreOrder::with('user')->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->order('pay_time', 'desc')
            ->limit(10)
            ->select()->toArray();
        $data['pay_type'] = [
            ['name' => '线上收银订单', 'value' => bcsub($data['order_amount'], bcadd($data['verify_amount'], $data['cash_amount'], 2), 2)],
            ['name' => '核销订单', 'value' => $data['verify_amount']],
            ['name' => '现金收银订单', 'value' => $data['cash_amount']],
        ];
        return $data;
    }


    /**
     * @notes 常用功能
     * @return array[]
     * @author 乔峰
     * @date 2021/12/29 16:40
     */
    public static function menu(): array
    {
        return [
            [
                'name' => '管理员',
                'image' => FileService::getFileUrl(config('project.default_image.menu_admin')),
                'url' => '/permission/admin'
            ],
            [
                'name' => '角色管理',
                'image' => FileService::getFileUrl(config('project.default_image.menu_role')),
                'url' => '/permission/role'
            ],
            [
                'name' => '部门管理',
                'image' => FileService::getFileUrl(config('project.default_image.menu_dept')),
                'url' => '/organization/department'
            ],
            [
                'name' => '素材中心',
                'image' => FileService::getFileUrl(config('project.default_image.menu_file')),
                'url' => '/material/index'
            ],
            [
                'name' => '菜单权限',
                'image' => FileService::getFileUrl(config('project.default_image.menu_auth')),
                'url' => '/permission/menu'
            ],
            [
                'name' => '网站信息',
                'image' => FileService::getFileUrl(config('project.default_image.menu_web')),
                'url' => '/setting/website/information'
            ],
        ];
    }


    /**
     * @notes 版本信息
     * @return array
     * @author 乔峰
     * @date 2021/12/29 16:08
     */
    public static function versionInfo(): array
    {
        return [
            'version' => config('project.version'),
            'website' => config('project.website.url'),
            'name' => ConfigService::get('website', 'name'),
            'based' => 'vue3.x、ElementUI、MySQL',
            'channel' => [
                'website' => 'https://gitee.com/MuZJun/gather-admin.git',
                'gitee' => 'https://gitee.com/MuZJun/gather-vue.git',
            ]
        ];
    }


    /**
     * @notes 今日数据
     * @return int[]
     * @author 乔峰
     * @date 2021/12/29 16:15
     */
    public static function today(): array
    {
        return [
            'time' => date('Y-m-d H:i:s'),
            // 今日销售额
            'today_sales' => 100,
            // 总销售额
            'total_sales' => 1000,

            // 今日访问量
            'today_visitor' => 10,
            // 总访问量
            'total_visitor' => 100,

            // 今日新增用户量
            'today_new_user' => 30,
            // 总用户量
            'total_new_user' => 3000,

            // 订单量 (笔)
            'order_num' => 12,
            // 总订单量
            'order_sum' => 255
        ];
    }


    /**
     * @notes 访问数
     * @return array
     * @author 乔峰
     * @date 2021/12/29 16:57
     */
    public static function visitor(): array
    {
        $num = [];
        $date = [];
        for ($i = 0; $i < 15; $i++) {
            $where_start = strtotime("- " . $i . "day");
            $date[] = date('Y/m/d', $where_start);
            $num[$i] = rand(0, 100);
        }

        return [
            'date' => $date,
            'list' => [
                ['name' => '访客数', 'data' => $num]
            ]
        ];
    }


    /**
     * @notes 服务支持
     * @return array[]
     * @author 乔峰
     * @date 2022/7/18 11:18
     */
    public static function support()
    {
        return [
            [
                'image' => FileService::getFileUrl(config('project.default_image.qq_group')),
                'title' => '官方公众号',
                'desc' => '关注官方公众号',
            ],
            [
                'image' => FileService::getFileUrl(config('project.default_image.customer_service')),
                'title' => '添加企业客服微信',
                'desc' => '想了解更多请添加客服',
            ]
        ];
    }

    public static function product($params)
    {
        $data = [];
        $storeId = $params['store_id'];
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];
        $endTime = date('Y-m-d', strtotime($endTime) + 86400);
        $dateDiff = (new \DateTime($endTime))->diff(new \DateTime($startTime));
        $data['visit_count'] = StoreVisit::where('store_id', $storeId)->whereBetweenTime('create_time', $startTime, $endTime)->count();
        $data['visit_user_count'] = StoreVisit::where('store_id', $storeId)->whereBetweenTime('create_time', $startTime, $endTime)->group('uid')->count();
        $data['add_cart_count'] = Cart::where('store_id', $storeId)->whereBetweenTime('create_time', $startTime, $endTime)->withTrashed()->group('product_id')->count();
        $data['add_order_count'] = StoreOrderCartInfo::where('store_id', $storeId)->whereBetweenTime('create_time', $startTime, $endTime)->withTrashed()->group('product_id')->count();
        $data['pay_count'] = StoreOrder::alias('t1')
            ->join('store_order_cart_info t2', 't1.id = t2.oid')
            ->where('t1.store_id', $storeId)
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group('product_id')
            ->count();
        $data['pay_amount'] = StoreOrder::where('store_id', $storeId)
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->sum('pay_price');
        $data['cost_amount'] = StoreOrder::where('store_id', $storeId)
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->sum('cost');
        $data['refund_amount'] = StoreOrder::where('store_id', $storeId)
            ->where('paid', 1)
            ->where('refund_status', '>',  0)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->sum('pay_price');
        $data['refund_count'] = StoreOrder::alias('t1')
            ->join('store_order_cart_info t2', 't1.id = t2.oid')
            ->where('t1.store_id', $storeId)
            ->where('paid', 1)
            ->where('refund_status', '>',  0)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group('product_id')
            ->count();
        $payUserCount = StoreOrder::where('store_id', $storeId)
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group('uid')
            ->count();
        if ($data['visit_user_count'] == 0) {
            $data['trans_rate'] = 0;
        } else {
            $data['trans_rate'] = bcdiv($payUserCount * 100, $data['visit_user_count'], 2);
        }
        //商品图表统计开始,未完成
        if ($dateDiff->days == 1) {
            $group = 'HOUR(pay_time)';
            $i = 0;
            while ($i < 24) {
                $timeRange[] = date('H', strtotime("+$i hours", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%H") as pay_time,sum(pay_price) as pay_price';
        } elseif ($dateDiff->days <= 31) {
            $group = 'DAY(pay_time)';
            $i = 0;
            while ($i < $dateDiff->days) {
                $timeRange[] = date('m-d', strtotime("+$i days", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%m-%d") as pay_time,sum(pay_price) as pay_price';
        } else {
            $group = 'MONTH(pay_time)';
            $i = 0;
            $month = 0;
            if ($dateDiff->y > 0) {
                $month = $dateDiff->y * 12;
            }
            if ($dateDiff->m > 0) {
                $month += $dateDiff->m;
            }
            if ($dateDiff->d > 0) {
                $month += 1;
            }
            while ($i < $month) {
                $timeRange[] = date('Y-m', strtotime("+$i months", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%Y-%m") as pay_time,sum(pay_price) as pay_price';
        }
        $orderList = StoreOrder::field($field)
            ->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group($group)
            ->select()
            ->toArray();
        $userList = StoreOrder::field($field . ',count(uid) as user_num')
            ->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group($group . ',uid')
            ->select()
            ->toArray();
        $orderList = reset_index($orderList, 'pay_time');
        $userList = reset_index($userList, 'pay_time');
        $orderListTmp = [];
        $userListTmp = [];
        $range = [];
        foreach ($timeRange as $item) {
            $range[] = $item;
            if (!isset($orderList[$item])) {
                $orderListTmp[$item] = 0;
            } else {
                $orderListTmp[$item] = $orderList[$item]['pay_price'];
            }
            if (!isset($userList[$item])) {
                $userListTmp[$item] = 0;
            } else {
                $userListTmp[$item] = $userList[$item]['user_num'];
            }
        }
        $data['statistics'] = [
            'range' => $range,
            'data' => [
                'order_amount' => array_values($orderListTmp),
                'user_number' => array_values($userListTmp)
            ]
        ];
        //商品图表统计结束

        // 商品排行榜,未完成
        $data['rank_list'] = StoreOrder::with('user')->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->whereBetweenTime('create_time', $startTime, $endTime)
            ->order('create_time', 'desc')
            ->limit(10)
            ->select()->toArray();
        return $data;
    }

    public static function delivery($params)
    {
        $data = [];
        $storeId = $params['store_id'];
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];
        $endTime = date('Y-m-d', strtotime($endTime) + 86400);
        $dateDiff = (new \DateTime($endTime))->diff(new \DateTime($startTime));
        $timeRange = [];
        if ($dateDiff->days == 1) {
            $group = 'HOUR(pay_time)';
            $i = 0;
            while ($i < 24) {
                $timeRange[] = date('H', strtotime("+$i hours", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%H") as pay_time,sum(pay_price) as pay_price,count(id) as order_num';
        } elseif ($dateDiff->days <= 31) {
            $group = 'DAY(pay_time)';
            $i = 0;
            while ($i < $dateDiff->days) {
                $timeRange[] = date('m-d', strtotime("+$i days", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%m-%d") as pay_time,sum(pay_price) as pay_price,count(id) as order_num';
        } else {
            $group = 'MONTH(pay_time)';
            $i = 0;
            $month = 0;
            if ($dateDiff->y > 0) {
                $month = $dateDiff->y * 12;
            }
            if ($dateDiff->m > 0) {
                $month += $dateDiff->m;
            }
            if ($dateDiff->d > 0) {
                $month += 1;
            }
            while ($i < $month) {
                $timeRange[] = date('Y-m', strtotime("+$i months", strtotime($startTime)));
                $i++;
            }
            $field = 'from_unixtime(pay_time,"%Y-%m") as pay_time,sum(pay_price) as pay_price,count(id) as order_num';
        }
        $amountList = StoreOrder::field($field)
            ->where('store_id', $storeId)
            ->where('paid', 1)
            ->where('shipping_type', 1)
            ->whereBetweenTime('pay_time', $startTime, $endTime)
            ->group($group)
            ->select()
            ->toArray();
        $amountList = reset_index($amountList, 'pay_time');
        $amountListTmp = [];
        $countListTmp = [];
        $range = [];
        foreach ($timeRange as $item) {
            $range[] = $item;
            if (!isset($amountList[$item])) {
                $amountListTmp[$item] = 0;
            } else {
                $amountListTmp[$item] = $amountList[$item]['pay_price'];
            }
            if (!isset($amountList[$item])) {
                $countListTmp[$item] = 0;
            } else {
                $countListTmp[$item] = $amountList[$item]['order_num'];
            }
        }
        $data['statistics'] = [
            'range' => $range,
            'data' => [
                'order_amount' => array_values($amountListTmp),
                'order_count' => array_values($countListTmp)
            ]
        ];
        return $data;
    }

    public static function deliveryOrder($params)
    {
        $startTime = $params['start_time'];
        $endTime = $params['end_time'];
        $endTime = date('Y-m-d', strtotime($endTime) + 86400);
        $query = StoreOrder::with('user')->where('store_id', $params['store_id'])
            ->where('paid', 1)
            ->where('shipping_type', 1)
            ->whereBetweenTime('create_time', $startTime, $endTime);
        $data['count'] = $query->count();
        $data['page_no'] = $params['page_no'];
        $data['page_size'] = $params['page_size'];
        $data['extend'] = [];
        $data['lists'] = $query->order('create_time', 'desc')
            ->page($params['page_no'], $params['page_size'])
            ->select()->toArray();
        return $data;
    }

}