<?php


namespace JinDouYun\Model\Cashier;

use JinDouYun\Controller\Common\Logger;
use JinDouYun\Dao\Cashier\DCashierConnectLog;
use JinDouYun\Dao\Cashier\DCashierCustomerPrice;
use JinDouYun\Dao\Cashier\DCashierEntryData;
use JinDouYun\Dao\Cashier\DCashierPushMoneyDetail;
use JinDouYun\Dao\Cashier\DCashierSettings;
use JinDouYun\Dao\Customer\DCustomer;
use JinDouYun\Dao\Department\DStaff;
use JinDouYun\Dao\Order\DOrder;
use JinDouYun\Dao\Order\DOrderIndex;
use JinDouYun\Dao\UserCenter\DUserCenter;
use JinDouYun\Model\Customer\MShippingAddress;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;

/**
 * Description:
 * Class MCashier
 * @package JinDouYun\Model\Cashier
 */
class MCashier
{
    /**
     * @var int
     */
    private $onlineUserId;

    /**
     * @var int
     */
    private $onlineEnterpriseId;

    /**
     * @var DOrderIndex
     */
    private $objDOrderIndex;

    /**
     * @var DCashierSettings
     */
    private $objDCashierSettings;

    /**
     * @var array 收银台配置信息
     */
    private $setting = [];

    /**
     * @var DStaff
     */
    private $objDStaff;

    /**
     * @var int 单表数据量
     */
    private $cutTable = 200000;

    /**
     * @var DOrder
     */
    private $objDOrder;

    /**
     * @var DCashierPushMoneyDetail
     */
    private $objDCashierPushMoneyDetail;

    /**
     * @var DCashierConnectLog
     */
    private $objDCashierConnectLog;

    /**
     * @var DCashierEntryData
     */
    private $objDCashierEntryData;

    /**
     * @var DCashierCustomerPrice
     */
    private $objDCashierCustomerPrice;

    /**
     * MCashier constructor.
     * @param $onlineUserId
     * @param $onlineEnterpriseId
     * @throws \Exception
     */
    public function __construct($onlineUserId, $onlineEnterpriseId)
    {
        $this->onlineUserId = $onlineUserId;
        $this->onlineEnterpriseId = $onlineEnterpriseId;
        $this->objDOrderIndex = new DOrderIndex();
        $this->objDOrderIndex->setTable('qianniao_order_index_'.$this->onlineEnterpriseId);
        $this->objDCashierSettings = new DCashierSettings();
        $this->objDStaff = new DStaff();
        $this->objDStaff->setTable('qianniao_staff_'.$this->onlineEnterpriseId);
        $this->objDOrder = new DOrder();
        $this->objDCashierPushMoneyDetail = new DCashierPushMoneyDetail();
        $this->objDCashierPushMoneyDetail->setTable('qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId);
        $this->objDCashierConnectLog = new DCashierConnectLog();
        $this->objDCashierConnectLog->setTable('qianniao_cashier_connect_log_'.$this->onlineEnterpriseId);
        $this->objDCashierEntryData = new DCashierEntryData();
        $this->objDCashierEntryData->setTable('qianniao_cashier_entry_data_'.$this->onlineEnterpriseId);
        $this->objDCashierCustomerPrice = new DCashierCustomerPrice();
        $this->objDCashierCustomerPrice->setTable('qianniao_cashier_customer_price_'.$this->onlineEnterpriseId);
    }

    /**
     * Doc: (des="计算订单的提成")
     * User: XMing
     * Date: 2020/9/2
     * Time: 12:18 下午
     * @param int $orderId
     * @return ResultWrapper
     * @throws \Exception
     */
    public function calculatePushMoney(int $orderId)
    {
        $settingResult = self::getCashierSetting();
        if (!$settingResult->isSuccess()){
            return ResultWrapper::fail($settingResult->getData(),$settingResult->getErrorCode());
        }
        $this->setting = $settingResult->getData()['add_form'];
        if (!isset($this->setting['guide_push_money'])){
            return ResultWrapper::fail('未获取到导购员配置',ErrorCode::$paramError);
        }
        $guide_push_money = $this->setting['guide_push_money'];
        if (!isset($this->setting['cashier_push_money'])){
            return ResultWrapper::fail('未获取到收银员配置',ErrorCode::$paramError);
        }
        $cashier_push_money = $this->setting['cashier_push_money'];
        $orderIndexInfo = $this->objDOrderIndex->get(['id' => $orderId]);
        if ($orderIndexInfo === false){
            return ResultWrapper::fail($this->objDOrderIndex->error(),ErrorCode::$dberror);
        }
        if (empty($orderIndexInfo)){
            return ResultWrapper::fail('未获取到指定订单',ErrorCode::$paramError);
        }
        $fix = (int)ceil($orderIndexInfo['userCenterId'] / $this->cutTable);
        //切换分表
        $this->objDOrder->setTable('qianniao_order_'.$this->onlineEnterpriseId.'_'.$fix);
        $order = $this->objDOrder->get(['id' => $orderId]);
        if ($order === false){
            return ResultWrapper::fail($this->objDOrder->error(),ErrorCode::$dberror);
        }
        if (empty($order)){
            return ResultWrapper::fail('未获取到指定的订单',ErrorCode::$paramError);
        }
        $orderMap = [
            'cashierUid'  => $order['cashierUid'],
            'guideUids'   => $order['guideUids'],
            'orderId' => $orderId,
            'payMoney' => $order['payAmount'],
            'orderNo' => $order['no'],
            'shopId' => $order['shopId'],
            'payType' => $order['payType']
        ];
        //是否开启导购提成
        $insertLogMap = [];
        $staffMap = [];
        if ($guide_push_money['status'] == StatusCode::$standard){
            $buildGuideDataResult = self::buildGuidePushMoney($guide_push_money['type'],$guide_push_money['push_money_rate'],$orderMap);
            if (!$buildGuideDataResult->isSuccess()){
                return ResultWrapper::fail($buildGuideDataResult->getData(),$buildGuideDataResult->getErrorCode());
            }
            $buildGuideData = $buildGuideDataResult->getData();
            if (!empty($buildGuideData)){
                $buildGuideLogMap =  $buildGuideData['buildLogMap'];
                $buildGuideStaffMap = $buildGuideData['buildStaffMap'];
                $insertLogMap = array_merge($insertLogMap,$buildGuideLogMap);
                $staffMap = array_merge($staffMap,$buildGuideStaffMap);
            }
        }else{
            Logger::logs(E_USER_ERROR,'未开启导购提成',__CLASS__,__LINE__,$this->setting);
        }
        //是否开启收银提成
        if ($cashier_push_money['status'] == StatusCode::$standard){
            $buildCashierDataResult = self::buildCashierPushMoney($cashier_push_money['type'],$cashier_push_money['push_money_rate'],$orderMap);
            if (!$buildCashierDataResult->isSuccess()){
                return ResultWrapper::fail($buildCashierDataResult->getData(),$buildCashierDataResult->getErrorCode());
            }
            $buildLogData = $buildCashierDataResult->getData();
            if (!empty($buildLogData)){
                $buildCashierLogMap =  $buildLogData['buildLogMap'];
                $buildCashierStaffMap = $buildLogData['buildStaffMap'];
                $insertLogMap = array_merge($insertLogMap,$buildCashierLogMap);
                $staffMap = array_merge($staffMap,$buildCashierStaffMap);
            }
        }else{
            Logger::logs(E_USER_ERROR,'未开启收银提成',__CLASS__,__LINE__,$this->setting);
        }
        $this->objDStaff->beginTransaction();
        //处理收银员/导购员的提成，
        if (!empty($staffMap)){
            $staffUpdateResult = self::buildStaffMoney($staffMap);
            if (!$staffUpdateResult->isSuccess()){
                return ResultWrapper::fail($staffUpdateResult->getData(),$staffUpdateResult->getErrorCode());
            }
            $staffUpdate = $staffUpdateResult->getData();
            Logger::logs(E_USER_ERROR,'员工余额变动数据',__CLASS__,__LINE__,$staffUpdate);
            foreach ($staffUpdate as $value){
                $updateResult = $this->objDStaff->update(['balance' => $value['balance'],'updateTime' => time()],['userCenterId' => $value['userCenterId']]);
                if ($updateResult === false){
                    $this->objDStaff->rollBack();
                    return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
                }
            }
        }
        if (!empty($insertLogMap)){
            Logger::logs(E_USER_ERROR,'提成记录插入数据',__CLASS__,__LINE__,$insertLogMap);
            $insertResult = $this->objDCashierPushMoneyDetail->insert($insertLogMap,true);
            if ($insertResult === false){
                $this->objDStaff->rollBack();
                return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
            }
        }

        //回写收银金额
        if (!empty($orderMap['payMoney'])){
           $writeCashierMoneyResult = self::writeCashierMoney($orderMap['cashierUid'],$orderMap['payMoney'],$orderMap['payType'],$orderMap['shopId']);
           if (!$writeCashierMoneyResult->isSuccess()){
               $this->objDStaff->rollBack();
               return ResultWrapper::fail($writeCashierMoneyResult->getData(),$writeCashierMoneyResult->getErrorCode());
           }
           $writeCashierMoneyData = $writeCashierMoneyResult->getData();
           $logId = $writeCashierMoneyData['id'];
           unset($writeCashierMoneyData['id']);
           $logUpdate = $this->objDCashierConnectLog->update($writeCashierMoneyData,['id' => $logId]);
           if ($logUpdate === false){
               $this->objDStaff->rollBack();
               return ResultWrapper::fail($this->objDCashierConnectLog->error(),ErrorCode::$dberror);
           }
        }

        $this->objDStaff->commit();
        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/9/2
     * Time: 6:36 下午
     * @param int $cashierUid
     * @param float $money
     * @param $payType
     * @param $shopId
     * @return ResultWrapper
     */
    private function writeCashierMoney(int $cashierUid,float $money,$payType,$shopId)
    {
        //获取当前的收银员的交接记录
        $cashierLog = $this->objDCashierConnectLog->get(['userCenterId' => $cashierUid,'shopId' => $shopId,'workStatus' => StatusCode::$auditStatus['auditIng']]);
        if ($cashierLog === false){
            return ResultWrapper::fail($this->objDCashierConnectLog->error(),ErrorCode::$dberror);
        }
        if (empty($cashierLog)){
            return ResultWrapper::fail('获取当前收银员工作记录失败',ErrorCode::$paramError);
        }
        $oldCollectionMoney = $cashierLog['collectionMoney'];
        $collectionData = empty($cashierLog['collectionData']) ? [] : json_decode($cashierLog['collectionData'],true);
        if (empty($collectionData)){
            $collectionData = [
                'other' => '0.00',
                'alipay' => '0.00',
                'balance' => '0.00',
                'cash' => '0.00',
                'wechat' => '0.00'
            ];
            switch ($payType){
                case StatusCode::$payType['cash']:
                    $collectionData['cash'] = $money;
                    break;
                case StatusCode::$payType['other']:
                    //其他
                    $collectionData['other'] = $money;
                    break;
                default:
                    $collectionData['other'] = $money;
                    break;
            }
        }else{
            switch($payType){
                case StatusCode::$payType['cash']:
                    $old = isset($collectionData['cash']) ? $collectionData['cash'] : 0;
                    $collectionData['cash'] = bcadd($old,$money,2);
                    break;
                case StatusCode::$payType['other']:
                    //其他
                    $old = isset($collectionData['other']) ? $collectionData['other'] : 0;
                    $collectionData['other'] = bcadd($old,$money,2);
                    break;
                default:
                    $old = isset($collectionData['other']) ? $collectionData['other'] : 0;
                    $collectionData['other'] = bcadd($old,$money,2);
                    break;
            }
        }
        $update = [
            'collectionMoney' => bcadd($oldCollectionMoney,$money,2),
            'collectionData' => \json_encode($collectionData),
            'id' => $cashierLog['id'],
            'updateTime' => time()
        ];
        Logger::logs(E_USER_ERROR,'收银统计信息',__CLASS__,__LINE__,$update);
        return ResultWrapper::success($update);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/9/2
     * Time: 5:04 下午
     * @param array $staffMap
     * @return ResultWrapper
     */
    private function buildStaffMoney(array $staffMap)
    {
        $allUids = [];
        foreach ($staffMap as $value){
            $allUids[] = $value['userCenterId'];
        }
        $staffLists = $this->objDStaff->select(['userCenterId' => $allUids]);
        if ($staffLists === false){
            return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
        }
        if (empty($staffLists)){
            return ResultWrapper::fail('未查询到员工数据',ErrorCode::$paramError);
        }
        $map = [];
        foreach ($staffLists as $value){
            $map[$value['userCenterId']] = $value;
        }
        foreach ($staffMap as $key => $item){
            if (!isset($map[$item['userCenterId']])){
                unset($staffMap[$key]);
                continue;
            }
            $oldBalance = $map[$item['userCenterId']]['balance'];
            $changeBalance = $item['retMoney'];
            $balance = bcadd($oldBalance,$changeBalance,2);
            $staffMap[$key]['balance'] = $balance;
            $staffMap[$key]['oldBalance'] = $oldBalance;
        }
        return ResultWrapper::success($staffMap);
    }

    /**
     * Doc: (des="获取首映台配置")
     * User: XMing
     * Date: 2020/9/2
     * Time: 2:19 下午
     * @return ResultWrapper
     */
    private function getCashierSetting()
    {
        $setting = $this->objDCashierSettings->get_field('content',['enterpriseId'=>$this->onlineEnterpriseId]);
        if ($setting === false){
            return ResultWrapper::fail($this->objDCashierSettings->error(),ErrorCode::$dberror);
        }
        if (empty($setting)){
            return ResultWrapper::fail('收银台设置为空',ErrorCode::$paramError);
        }
        $setting = json_decode($setting,true);
        return ResultWrapper::success($setting);
    }

    /**
     * Doc: (des="计算导购提成")
     * User: XMing
     * Date: 2020/9/2
     * Time: 2:38 下午
     * @param int $type
     * @param float $rate
     * @param array $orderData
     * @return ResultWrapper
     */
    private function buildGuidePushMoney(int $type,float $rate,array $orderData)
    {
        //查询导购是否开启自定义提成
        $guideUidsStr = $orderData['guideUids'];
        if (empty($guideUidsStr)){
            return ResultWrapper::success([]);
        }
        $guideUidIds = explode(',',$guideUidsStr);
        $staffLists =  $this->objDStaff->select(['userCenterId' => $guideUidIds]);
        if ($staffLists === false){
            return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
        }
        if (empty($staffLists)){
            return ResultWrapper::fail('未获取到导购的信息',ErrorCode::$paramError);
        }
        $staffMap = [];
        foreach ($staffLists as $value){
            $staffMap[$value['userCenterId']] = $value;
        }
        $map = [];
        foreach ($guideUidIds  as $uid){
            if (!isset($staffMap[$uid])){
                //没有获取到，一般情况下是不存在的，除非有脏数据
                continue;
            }
            if ($staffMap[$uid]['isSetRule'] == StatusCode::$standard){
                //设置了自定义的规则
                $rule = json_decode($staffMap[$uid]['rule'],true);
                $map[$uid] = [
                    'type' => $rule['push_money_type'],
                    'rate' => $rule['push_money_rate'],
                    'staffName' => $staffMap[$uid]['staffName'],
                    'userCenterId' => $staffMap[$uid]['userCenterId'],
                ];
                continue;
            }
            //默认的规则
            $map[$uid] = [
                'type' => $type,
                'rate' => $rate,
                'staffName' => $staffMap[$uid]['staffName'],
                'userCenterId' => $staffMap[$uid]['userCenterId'],
            ];
        }

        $buildStaffMap = [];
        $buildLogMap = [];
        //计算导购员的提成
        foreach ($map as $uid => $item){
            $retMoney = 0;
            switch ($item['type']){
                case StatusCode::$delete:
                    //按订单
                    $retMoney = $item['rate'];
                    break;
                case StatusCode::$standard:
                    //按订单金额
                    if (empty($item['rate'])){
                        continue 2;
                    }
                    $rate = bcdiv($item['rate'],100,2);
                    $retMoney = bcmul($rate,$orderData['payMoney'],2);
                    break;
            }
            $buildStaffMap[] = [
                'userCenterId' => $uid,
                'retMoney' => $retMoney
            ];
            $buildLogMap[] = [
                'pushType' => 2,
                'staffName' => $item['staffName'],
                'orderId' => $orderData['orderId'],
                'orderNo' => $orderData['orderNo'],
                'orderMoney' => $orderData['payMoney'],
                'pushMoneyRate' => $item['rate'],
                'pushMoney' => $retMoney,
                'auditStatus' => StatusCode::$auditStatus['auditPass'],
                'auditTime' => time(),
                'createTime' => time(),
                'shopId' => $orderData['shopId'],
                'userCenterId' => $item['userCenterId']
            ];
        }
        return ResultWrapper::success([
            'buildStaffMap' => $buildStaffMap,
            'buildLogMap' => $buildLogMap
        ]);
    }

    /**
     * Doc: (des="计算收银提成")
     * User: XMing
     * Date: 2020/9/2
     * Time: 2:39 下午
     * @param int $type
     * @param float $rate
     * @param array $orderData
     * @return ResultWrapper
     */
    private function buildCashierPushMoney(int $type,float $rate,array $orderData)
    {
        $cashierUid = $orderData['cashierUid'];
        if (empty($cashierUid)){
            return ResultWrapper::success([]);
        }
        $staffInfo = $this->objDStaff->get(['userCenterId' => $cashierUid]);
        if ($staffInfo === false){
            return ResultWrapper::fail($this->objDStaff->error(),ErrorCode::$dberror);
        }
        if (empty($staffInfo)){
            return ResultWrapper::success([
                'buildStaffMap' => [],
                'buildLogMap' => []
            ]);
        }
        if ($staffInfo['isSetRule'] == StatusCode::$standard){
            $rule = json_decode($staffInfo['rule'],true);
            $type = $rule['push_money_type'];
            $rate = $rule['push_money_rate'];
        }

        //计算收银员工的提成
        $retMoney = 0;
        switch ($type) {
            case StatusCode::$delete:
                //按订单
                $retMoney = $rate;
                break;
            case StatusCode::$standard:
                //按订单金额
                if (empty($rate)) {
                    return ResultWrapper::fail('提成百分比设置为空', ErrorCode::$paramError);
                }
                $retMoney = bcmul(bcdiv($rate, 100, 2), $orderData['payMoney'], 2);
                break;
        }

        $buildStaffMap[] = [
            'retMoney' => $retMoney,
            'userCenterId' => $cashierUid,
        ];
        $buildLogMap[] = [
            'pushType' => 1,
            'staffName' => $staffInfo['staffName'],
            'orderId' => $orderData['orderId'],
            'orderNo' => $orderData['orderNo'],
            'orderMoney' => $orderData['payMoney'],
            'pushMoneyRate' => $rate,
            'pushMoney' => $retMoney,
            'auditStatus' => StatusCode::$auditStatus['auditPass'],
            'auditTime' => time(),
            'createTime' => time(),
            'shopId' => $orderData['shopId'],
            'userCenterId' => $staffInfo['userCenterId']
        ];
        return ResultWrapper::success([
            'buildStaffMap' => $buildStaffMap,
            'buildLogMap' => $buildLogMap
        ]);
    }

    /**
     * Doc: (des="统计项")
     * User: XMing
     * Date: 2020/9/3
     * Time: 3:22 下午
     * @param array $params
     * @return ResultWrapper
     */
    public function overView(array $params)
    {
        $cashier_push_money_result = self::getPushMoneyBySql(StatusCode::$roleId['cashier'],$params);
        if (!$cashier_push_money_result->isSuccess()){
            return ResultWrapper::fail($cashier_push_money_result->getData(),$cashier_push_money_result->getErrorCode());
        }

        $guide_push_money_result = self::getPushMoneyBySql(StatusCode::$roleId['guide'],$params);
        if (!$guide_push_money_result->isSuccess()){
            return ResultWrapper::fail($guide_push_money_result->getData(),$guide_push_money_result->getErrorCode());
        }

        $orderResult = self::getPushOrderNumBySql($params);
        if (!$orderResult->isSuccess()){
            return ResultWrapper::fail($orderResult->getData(),$orderResult->getErrorCode());
        }
        $orderMap = $orderResult->getData();

        //提成统计
        $listResult = self::getListBySql($params,(isset($params['type']) && !empty($params['type'])) ? $params['type'] : StatusCode::$roleId['cashier']);
        if (!$listResult->isSuccess()){
            return ResultWrapper::fail($listResult->getData(),$listResult->getErrorCode());
        }
        $list = $listResult->getData();

        $data = [
            'statistics'=>[
                'cashier_push_money' => $cashier_push_money_result->getData(),
                'guide_push_money' => $guide_push_money_result->getData(),
                'order_num' => $orderMap['num'],
                'order_pay_price' => $orderMap['payAmount']
            ],
            'list' => $list['data'],
            'screen_time' => [
                'startTime' => $params['startTime'],
                'endTime' => $params['endTime'],
            ],
        ];

        $ret = [
            'total' => $list['total'],
            'data'  => $data
        ];
        return ResultWrapper::success($ret);
    }

    /**
     * Doc: (des="统计列表数据")
     * User: XMing
     * Date: 2020/9/15
     * Time: 11:33 上午
     * @param array $params
     * @param int $pushType
     * @return ResultWrapper
     */
    private function getListBySql(array $params,int $pushType = 1)
    {
        $fields = '*,SUM(pushMoney) AS totalPushMoney,SUM(orderMoney) AS totalOrderMoney,COUNT(id) AS num';
        $sql = 'SELECT '.$fields.' FROM qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId.' WHERE pushType = '.$pushType;
        if (isset($params['startTime']) && !empty($params['startTime']) &&
            isset($params['endTime']) && !empty($params['endTime'])){
            $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
        }
        if (isset($params['userCenterId']) && !empty($params['userCenterId'])){
            $sql .= ' AND userCenterId = '.$params['userCenterId'];
        }
        $sql .= ' GROUP BY userCenterId ORDER BY totalPushMoney DESC ';
        $count = count((array)$this->objDCashierPushMoneyDetail->query($sql));
        if (isset($params['limit']) && !empty($params['limit']) && isset($params['offset']) && !empty($params['offset'])){
            $sql .= ' LIMIT '.$params['offset'].','.$params['limit'];
        }
        $query = $this->objDCashierPushMoneyDetail->query($sql);
        if ($query === false){
            return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
        }

        $userMap = [];
        $allUserCenterIds = array_column($query,'userCenterId');
        if (!empty($allUserCenterIds)){
            $objDUserCenter = new DUserCenter();
            $userList = $objDUserCenter->select(['id' =>$allUserCenterIds],'id,mobile');
            if ($userList === false){
                return ResultWrapper::fail($objDUserCenter->error(),ErrorCode::$dberror);
            }
            foreach ($userList as $value){
                $userMap[$value['id']] = $value['mobile'];
            }
        }

        $map = [];
        foreach ($query as $value){
            $map[] = [
                'mobile' => isset($userMap[$value['userCenterId']]) ? $userMap[$value['userCenterId']] : '',
                'staffName' => $value['staffName'],
                'order_num' => $value['num'],
                'order_price' => $value['totalOrderMoney'],
                'shop_id' => $value['shopId'],
                'push_money' => $value['totalPushMoney'],
            ];
        }
        return ResultWrapper::success(['data'=>$map,'total'=>$count]);

    }

    /**
     * Doc: (des="统计收银,导购提成")
     * User: XMing
     * Date: 2020/9/15
     * Time: 9:59 上午
     * @param int $pushType
     * @param array $params
     * @return ResultWrapper
     */
    private function getPushMoneyBySql(int $pushType,array $params)
    {
        $fields = 'SUM(pushMoney) AS totalSum';
        $sql = 'SELECT '.$fields.' FROM qianniao_cashier_push_money_detail_'.$this->onlineEnterpriseId.' WHERE pushType = '.$pushType;
        if (isset($params['startTime']) && !empty($params['startTime']) &&
        isset($params['endTime']) && !empty($params['endTime'])){
            $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
        }
        $queryResult = $this->objDCashierPushMoneyDetail->query($sql);
        if ($queryResult === false){
            return ResultWrapper::fail($this->objDCashierPushMoneyDetail->error(),ErrorCode::$dberror);
        }
        $result = array_shift($queryResult);
        return ResultWrapper::success($result['totalSum']);
    }

    /**
     * Doc: (des="通过sql,统计订单数据量")
     * User: XMing
     * Date: 2020/9/15
     * Time: 10:11 上午
     * @param array $params
     * @return ResultWrapper
     */
    private function getPushOrderNumBySql(array $params)
    {
        $fields = 'id,userCenterId,id as orderId';
        $sql = 'SELECT '.$fields.' FROM qianniao_order_index_'.$this->onlineEnterpriseId.' WHERE orderType = '.StatusCode::$orderType['cashierOrder'];
        if (isset($params['startTime']) && !empty($params['startTime']) &&
            isset($params['endTime']) && !empty($params['endTime'])){
            $sql .= ' AND createTime BETWEEN '.$params['startTime'].' AND '.$params['endTime'];
        }
        $queryIndex = $this->objDOrderIndex->query($sql);
        if ($queryIndex === false){
            return ResultWrapper::fail($this->objDOrderIndex->error(),ErrorCode::$dberror);
        }
        unset($fields);
        unset($sql);
        //计算分表
        $allGroupData = [];
        foreach ($queryIndex as $key => $val) {
            $tableNum = ceil($val['userCenterId'] / $this->cutTable);
            $allGroupData[$tableNum][] = $val['orderId'];
        }

        $payAmount = 0;
        $fields = 'SUM(payAmount) as payAmount';
        foreach ($allGroupData as $k => $orderIds){
            if (!empty($orderIds)){
                $idStr = implode(',',$orderIds);
                $sql = 'SELECT '.$fields.' FROM qianniao_order_'.$this->onlineEnterpriseId.'_'.$k.'  WHERE id IN('.$idStr.')';
                $queryOrder = $this->objDOrder->query($sql);
                if ($queryOrder === false){
                    return ResultWrapper::fail($this->objDOrder->error(),ErrorCode::$dberror);
                }
                $result = array_shift($queryOrder);
                $payAmount = bcadd($payAmount,$result['payAmount'],2);
            }
        }

        return ResultWrapper::success([
            'payAmount' => $payAmount,
            'num'       => count((array)$queryIndex),
        ]);
    }
    

    /**
     * Doc: (des="根据手机号检索会员信息")
     * User: XMing
     * Date: 2020/9/11
     * Time: 2:57 下午
     * @param string $mobile
     * @return ResultWrapper
     * @throws \Exception
     */
    public function searchCustomerDetails(string $mobile)
    {
        $objDCustomer = new DCustomer();
        $objDCustomer->setTable('qianniao_customer_'.$this->onlineEnterpriseId);
        $fields = 'u.mobile,u.id as userCenterId,c.id as customerId,c.salesManId,c.avatar,c.name,c.birthday,c.provinceCode,c.cityCode,
                    c.districtCode,c.status,c.auditFailReason,c.enableStatus,c.type,c.shopId,c.remark,c.money,c.totalPayMoney,c.createTime';
        $sql = 'SELECT '.$fields.' FROM qianniao_user_center AS u 
                LEFT JOIN qianniao_customer_' .$this->onlineEnterpriseId .' AS c 
                ON u.id = c.userCenterId 
                AND u.mobile = ' . $mobile . ' LIMIT 1';
        $customerInfo = $objDCustomer->query($sql);
        if ($customerInfo === false) {
            return ResultWrapper::fail($objDCustomer->error(), ErrorCode::$dberror);
        }
        if (empty($customerInfo)) {
            return ResultWrapper::success([]);
        }
        $customerInfo = array_shift($customerInfo);
        if (empty($customerInfo['customerId'])){
            return ResultWrapper::success([]);
        }

        $objMShippingAddress = new MShippingAddress($this->onlineEnterpriseId);
        $addressListsResult = $objMShippingAddress->getAllShippingAddress(['customerId'=>$customerInfo['customerId'],'limit'=>10,'offset'=>0]);
        if (!$addressListsResult->isSuccess()){
            return ResultWrapper::fail($addressListsResult->getData(),$addressListsResult->getErrorCode());
        }
        $addressLists = $addressListsResult->getData()['data'];
        $defaultAddress = (object)[];
        if (!empty($addressLists)){
            foreach ($addressLists as $val){
                if ($val['defaultStatus'] == StatusCode::$standard){
                    $defaultAddress = $val;
                    break;
                }
            }
        }

        //统计客户订单数
        $objDOrderIndex = new DOrderIndex();
        $objDOrderIndex->setTable('qianniao_order_index_'.$this->onlineEnterpriseId);
        $orderNum = $objDOrderIndex->count(['customerId' => $customerInfo['customerId']]);
        if ($orderNum === false){
            return ResultWrapper::fail($objDOrderIndex->error(),ErrorCode::$dberror);
        }

        //根据用户id获取staffId

        $map = [
            'mobile' => $customerInfo['mobile'],
            'customerId' => $customerInfo['customerId'],
            'salesManId' => $customerInfo['salesManId'],
            'avatar' => $customerInfo['avatar'],
            'name'   => $customerInfo['name'],
            'remark' => is_null($customerInfo['remark']) ? '' : $customerInfo['remark'],
            'createTime' => $customerInfo['createTime'],
            'birthday'  => is_null($customerInfo['birthday']) ? 0 : $customerInfo['birthday'],
            'orderNum' => $orderNum,
            'vipCard'  => (object)[],
            'address'  => $addressLists,
            'defaultAddress' => $defaultAddress,
            'money' => bcadd($customerInfo['money'],0,2),
            'totalPayMoney' => bcadd($customerInfo['totalPayMoney'],0,2),
            'userCenterId' => $customerInfo['userCenterId']
        ];

        return ResultWrapper::success($map);
    }

    /**
     * Doc: (des="收银台挂单")
     * User: XMing
     * Date: 2020/9/12
     * Time: 6:05 下午
     * @param $data
     * @return ResultWrapper
     */
    public function saveEntryData($data)
    {
        $insert = $this->objDCashierEntryData->insert(
            [
                'shopId' => $data['shopId'],
                'entryData' => $data['entryData'],
                'userCenterId'=>$this->onlineUserId,
                'createTime' => time()
            ]
        );
        if ($insert === false){
            return ResultWrapper::fail($this->objDCashierEntryData->error(),ErrorCode::$dberror);
        }
        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="获取挂单记录")
     * User: XMing
     * Date: 2020/9/12
     * Time: 6:22 下午
     * @param array $selectParams
     * @return ResultWrapper
     */
    public function getAllEntryData(array $selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $dbResult = $this->objDCashierEntryData->select(['userCenterId'=>$this->onlineUserId,'shopId' => $selectParams['shopId']], '*', 'createTime DESC', $limit, $offset);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
        }
        foreach ($dbResult as &$value){
            $value['entryData'] = json_decode($value['entryData'],true);
        }
        $total = $this->objDCashierEntryData->count(['userCenterId'=>$this->onlineUserId,'shopId' => $selectParams['shopId']]);
        $return = [
            'data'  => $dbResult,
            'total' => ($total) ? intval($total) : 0,
        ];
        return ResultWrapper::success($return);
    }

    /**
     * Doc: (des="获取挂单")
     * User: XMing
     * Date: 2020/9/12
     * Time: 6:30 下午
     * @param int $id
     * @return ResultWrapper
     */
    public function getEntryData(int $id)
    {
        $result = $this->objDCashierEntryData->get(['id'=>$id]);
        if ($result === false) {
            return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
        }
        if (!empty($result)){
            $this->objDCashierEntryData->delete(['id'=>$id]);
            $result['entryData'] = json_decode($result['entryData'],true);
            return ResultWrapper::success($result);
        }
        return ResultWrapper::success([]);
    }

    /**
     * Doc: (des="删除挂单")
     * User: XMing
     * Date: 2020/9/12
     * Time: 6:39 下午
     * @param $id
     * @return ResultWrapper
     */
    public function delEntryData(int $id)
    {
        $result = $this->objDCashierEntryData->delete(['id' => $id]);
        if ($result === false) {
            return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="收银台商品改价")
     * User: XMing
     * Date: 2020/9/14
     * Time: 9:33 上午
     * @param array $params
     * @return ResultWrapper
     */
    public function changePrice(array $params)
    {
        $insert = [
            'skuId' => $params['skuId'],
            'price' => $params['changePrice'],
            'cashierUid' => $this->onlineUserId,
            'customerUid' => $params['customerUid']
        ];
        $insert = $this->objDCashierCustomerPrice->replace($insert);
        if ($insert === false) {
            return ResultWrapper::fail($this->objDCashierEntryData->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success(true);
    }
}