<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: huajie <banhuajie@163.com>
// +----------------------------------------------------------------------

namespace Admin\Model;
use Common\Api\GameApi;
use Org\WeixinSDK\Weixin;
use Think\Model;

/**
 * 文档基础模型
 */
class SpendModel extends Model{



    /* 自动验证规则 */
    protected $_validate = array();

    /* 自动完成规则 */
    protected $_auto = array(
        array('pay_time', 'getCreateTime', self::MODEL_INSERT,'callback'),
        array('pay_status',  0, self::MODEL_INSERT),
        array('order_number','',self::MODEL_INSERT),
    );

protected function  _after_select(&$result,$options){
   foreach($result as $key=>$value){
         // $result[$key]['pay_way'] = date('Y-m-d ', $value['time']);
   }
 }

    /**
     * 构造函数
     * @param string $name 模型名称
     * @param string $tablePrefix 表前缀
     * @param mixed $connection 数据库连接信息
     */
    public function __construct($name = '', $tablePrefix = '', $connection = '') {
        /* 设置默认的表前缀 */
        $this->tablePrefix ='tab_';
        /* 执行构造方法 */
        parent::__construct($name, $tablePrefix, $connection);
    }


    /**
     * 创建时间不写则取当前时间
     * @return int 时间戳
     * @author huajie <banhuajie@163.com>
     */
    protected function getCreateTime(){
        $create_time    =   I('post.create_time');
        return $create_time?strtotime($create_time):NOW_TIME;
    }

    public function amdin_account()
    {
       return session('user_auth.username');
    }
    public function totalSpendTimes($map=""){
        $map['s.pay_status'] = 1;
        $data = $this->alias("s")->field("IFNULL(count(pay_amount),0) as count")
            ->join("left join tab_game g on g.id = s.game_id")
            ->where($map)
            ->find();
        return $data['count'];
    }
    /**
     * [dealPage 页码处理]
     * @param  [type] $p [description]
     * @return [type]    [description]
     */
    public function dealPage($p){
        $page = intval($p);
        $page = $page ? $page : 1; //默认显示第一页数据
        return $page;
    }
    /**
     * 自动补单
     */
    public static function auto_repair(){
        $game = new GameApi();
        $map['pay_status'] =  1;
        $map['pay_game_status'] = 0;
        $order = M("spend",'tab_')->field('pay_order_number,1 as code')->where($map)->select();//普通消费
        $bind_spend = M("bind_spend",'tab_')->field('pay_order_number,2 as code')->where($map)->select();//绑币消费
        if(!empty($bind_spend)){
            array_push($order,$bind_spend);
        }
        $success_num = $error_num = 0;
        foreach ($order as $key=>$val) {
            $param['out_trade_no'] = $val['pay_order_number'];
            $result = $game->game_pay_notify($param, $val['code']);
            if($val['code'] == 1){
                M('spend','tab_')->where(['pay_order_number'=>$val['pay_order_number']])->setInc('auto_compensation');
            }else{
                M('bind_spend','tab_')->where(['pay_order_number'=>$val['pay_order_number']])->setInc('auto_compensation');
            }
            if($result == "success"){
                $success_num++;
            }else{
                $error_num++;
            }
        }
        $time = time_format0();
        \Think\Log::record("自动补单({$time}):成功 {$success_num} 个,失败:{$error_num}个");
    }


    /**
     * 退款接口
     * @param $map
     */
    public function Refund($map,$order,$sign)
    {
        if(md5("mcaseqwezdsi".$order)!==$sign){
                return false;
        }
        $RefundRecord = M('RefundRecord', 'tab_')->where($map)->find();
        if (null == $RefundRecord) {
            $find = $this->where($map)->find();
            $order_number = $find['pay_way'] == 1 ? date("YmdHis") : "TK_" . date('Ymd') . date('His') . sp_random_string(4);
            $BatchNo=date("YmdHis");
        } else {
            $order_number = $RefundRecord['order_number'];
            $BatchNo=$RefundRecord['batch_no'];
            $find = $RefundRecord;
        }

        if ($find['pay_way'] == 1) {
            //页面上通过表单选择在线支付类型,支付宝为alipay 财付通为tenpay
            $pay = new \Think\Pay('alipay', C('alipay'));
            $vo = new \Think\Pay\PayVo();
            $detail_data = $find['order_number'] . "^" . $find['pay_amount'] . "^调单";

            $find['batch_no']=$BatchNo;
            $vo->setOrderNo($find['order_number'])
                ->setService("refund_fastpay_by_platform_pwd")
                ->setSignType("MD5")
                ->setPayMethod("refund")
                ->setTable("RefundRecord")
                ->setBatchNo($BatchNo)
                ->setDetailData($detail_data);
            $this->add_refund_record($find, $find['order_number']);
            $this->where($map)->delete();
            return $pay->buildRequestForm($vo);
        } elseif ($find['pay_way'] == 3) {
            $weixn = new Weixin();
            $res = json_decode($weixn->weixin_Refund_pub($find['pay_order_number'], $order_number, $find['pay_amount'], $find['pay_amount'], C('wei_xin_app.partner')), true);
            $this->add_refund_record($find, $order_number);
            $this->where($map)->delete();
            if ($res['status'] == 1) {
                return $res['status'];
            } else {
                return $res;
            }

        } elseif ($find['pay_way'] == 4) {
            $config = array("partner" => trim(C("weixin.partner")), "email" => "", "key" => trim(C("weixin.key")));
            $pay = new \Think\Pay('swiftpass', $config);
            $vo = new \Think\Pay\PayVo();
             $vo->setService('unified.trade.refund')
                ->setSignType("MD5")
                ->setPayMethod("refund")
                ->setTable("RefundRecord")
                ->setOrderNo($find['pay_order_number'])
                ->setBatchNo($order_number)
                ->setFee($find['pay_amount']);
            $this->add_refund_record($find, $order_number);
             $this->where($map)->delete();
            $res=$pay->buildRequestForm($vo);
            if ($res['status'] == 0) {
                return $res['status'];
            } else {
                return false;
            }
        } elseif ($find['pay_way'] == 0) {
            $user_map['id'] = $find['user_id'];
            M('user', 'tab_')->where($user_map)->setInc('balance', $find['pay_amount']);
             $this->add_refund_record($find, $order_number);
             $this->where($map)->delete();
            return true;
        }

    }

    /**
     * 添加退款记录
     * @param $data
     * @return mixed
     */
    public function add_refund_record($data, $order_number)
    {
        $RefundRecord = M('RefundRecord', 'tab_');
        unset($data['id']);
        $map['pay_order_number'] = $data['pay_order_number'];
        $find = $RefundRecord->where($map)->find();
        if (null !== $find) {
            if($data['pay_way']==4||$data['pay_way']==3){
                $RefundRecord->where($map)->delete();
                $data['tui_status'] = 2;
                $data['create_time'] = time();
                $data['tui_amount'] = $data['pay_amount'];
                $data['order_number'] = $order_number;
                return $RefundRecord->add($data);
            }else{
                return true;
            }
        } else {
            if ($data['pay_way'] == 0) {
                $data['tui_status'] = 1;
                $data['tui_time'] = time();
                $savv['sub_status']=1;
                $savv['settle_check']=1;
                $this->where($map)->save($savv);
            }elseif($data['pay_way'] == 4||$data['pay_way']==3){
                $data['tui_status'] = 2;
            }

            $data['create_time'] = time();
            $data['tui_amount'] = $data['pay_amount'];
            $data['order_number'] = $order_number;
            return $RefundRecord->add($data);

        }
    }




    /**
     * 微信退款查询接口
     * @param  [type] $orderNo [description]
     * @return [type]          [description]
     */
    public function weixin_refundquery($orderNo){
          $weixn = new Weixin();
          $res = $weixn->weixin_refundquery($orderNo);
           if($res=="SUCCESS"){
            M('RefundRecord', 'tab_')->where(array('pay_order_number'=>$orderNo))->setField('tui_status', 1);
                return json_encode(array('status'=>1,'msg'=>'退款成功'));
            }elseif($res=="FAIL"){
                return json_encode(array('status'=>0,'msg'=>'退款失败'));
            }elseif($res=="PROCESSING"){
                return json_encode(array('status'=>0,'msg'=>'退款处理中'));
            }
    }



    /**
     * 威富通查询退款接口
     * @param  [type] $map [description]
     * @return [type]      [description]
     */
    public function swiftpass_refund($orderNo){
        $config = array("partner" => trim(C("weixin.partner")), "email" => "", "key" => trim(C("weixin.key")));
        $pay = new \Think\Pay('swiftpass', $config);
        $vo = new \Think\Pay\PayVo();
        $vo->setOrderNo($orderNo)
            ->setService('unified.trade.refundquery')
            ->setSignType("MD5")
            ->setPayMethod("find")
            ->setTable("RefundRecord");
        $res=$pay->buildRequestForm($vo);
        if($res['refund_status']=="SUCCESS"){
            M('RefundRecord', 'tab_')->where(array('pay_order_number'=>$orderNo))->setField('tui_status', 1);
            return json_encode(array('status'=>1,'msg'=>'退款成功'));
        }elseif($res['refund_status']=="FAIL"){
            return json_encode(array('status'=>0,'msg'=>'退款失败'));
        }elseif($res['refund_status']=="PROCESSING"){
            return json_encode(array('status'=>0,'msg'=>'退款处理中'));
        }
    }











	/**
	 * 开放平台 付费人数
	 * @param string $map
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
    public function countSpendUserOfOpen($map=""){
	    $sql = $this->alias("s")->field("s.user_id")
		    ->join("left join tab_game g on g.id = s.game_id")
		    ->where($map)
		    ->group("s.game_id,s.user_id")
		    ->select(false);
	    $sql = "select count(DISTINCT user_id) as num from ({$sql}) as res";
	    $data = M()->query($sql);
	    return $data[0]['num'];
    }

	/**
	 * 累计付费
	 * @param string $map
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
    public function totalSpend($map=""){
    	$map['s.pay_status'] = 1;
    	$data = $this->alias("s")->field("IFNULL(sum(pay_amount),0) as num")
		    ->join("right join tab_game g on g.id = s.game_id")
		    ->where($map)
		    ->find();
    	return $data['num'];
    }


	/**
	 * 获取开放平台流水
	 * @param $map
	 * @param $develop_id
	 * author: xmy 280564871@qq.com
	 */
    public function getOpenSpend($map,$develop_id,$game_id){
//	    empty($game_id) || $map['s.game_id'] = $game_id;
	    empty($game_id) || $join = "and g.id = {$game_id}";
	    $data = $this->alias("s")->field("IFNULL(sum(pay_amount),0) as num,d.time")
		    ->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id {$join}")
		    ->join("right join sys_date_list d on d.time = FROM_UNIXTIME(s.pay_time,'%Y-%m-%d') and s.pay_status = 1")
		    ->where($map)
		    ->group("d.time")
		    ->select();
	    return $data;
    }

	/**
	 * 付费玩家数
	 * @param $map
	 * @param $develop_id
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
    public function getPayerNum($map,$develop_id,$game_id){
//    	empty($game_id) || $map['s.game_id'] = $game_id;
    	empty($game_id) || $join = "and g.id = {$game_id}";
	    $data = $this->alias("s")->field("IFNULL(count(DISTINCT user_id),0) as num,d.time")
		    ->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id {$join}")
		    ->join("right join sys_date_list d on d.time = FROM_UNIXTIME(s.pay_time,'%Y-%m-%d') and s.pay_status = 1")
		    ->where($map)
		    ->group("d.time")
		    ->select();
	    return $data;
    }


	/**
	 * 新增付费玩家
	 * @param $start
	 * @param $end
	 * @param $develop_id
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
    public function getNewPayerNum($start,$end,$develop_id,$game_id){
    	//第一次充值
	    empty($game_id) || $map['s.game_id'] = $game_id;

	    $map['s.pay_status'] = 1;
	    $sql = $this->alias("s")->field("user_id,min(pay_time) as pay_time")
		    ->join("right join tab_game g on g.id = s.game_id and g.developers = $develop_id")
		    ->where($map)
		    ->group("s.user_id")
		    ->select(false);
	    $sql = "SELECT count(res.user_id) as num,d.time FROM ({$sql}) res right join sys_date_list d on d.time = FROM_UNIXTIME(res.pay_time,'%Y-%m-%d')
	    WHERE d.time BETWEEN '{$start}' and '{$end}' GROUP BY d.time";
	    $data = $this->query($sql);
	    return $data;
    }

	/**
	 * 累计付费玩家数(按天分组)
	 * @param $map
	 * @param $develop_id
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
    public function getTotalPayerNum($start,$end,$develop_id){
	    $start = strtotime($start);
	    $end = strtotime($end);
	    $map['g.developers'] = $develop_id;
			$map['s.pay_status'] = 1;
	    for ($time = $start; $time <= $end; $time += 86400) {
		    $map['s.pay_time'] = ['lt',$time+86399];
		    $data[]['num'] = $this->countSpendUserOfOpen($map);
	    }
	    return $data;
    }

	/**
	 * 累计流水
	 * @param $map
	 * @return mixed
	 * author: xmy 280564871@qq.com
	 */
	public function getTotalSpend($map){
		$map['pay_status'] = 1;
		$data = $this->field("IFNULL(sum(pay_amount),0) as num")->where($map)->find();
		return $data;
	}

	/*
	 * 游戏充值未到账列表
	 * @return array  结果集
	 * @author 鹿文学
	 */
	public function checkSpend() {

		$list = $this->field('id,user_id,user_account,game_id,game_name,pay_amount,pay_order_number')->where(array('pay_status'=>0))->select();
		$type = 101;
		if ($list[0]) {

			$list = D('check')->dealWithCheckList($type,$list);

			if (empty($list[0])) {return '';}

			foreach ($list as $k => $v) {
				$data[$k]['info'] = '玩家:'.$v['user_account'].',游戏['.$v['game_name'].']充值金额:'.$v['pay_amount'].',订单状态:下单未支付';
				$data[$k]['type'] = $type;
				$data[$k]['url'] = U('Spend/lists',array('pay_order_number'=>$v['pay_order_number']));
				$data[$k]['create_time'] = time();
				$data[$k]['status']=0;
				$data[$k]['position'] = $v['id'];
			}
			return $data;
		}else {
			D('check')->dealWithCheckListOnNull($type);
			return '';
		}

	}

	/*
	 * 游戏补单列表
	 * @return array  结果集
	 * @author 鹿文学
	 */
	public function checkSupplement() {

		$list = $this->field('id,user_id,user_account,pay_order_number')->where(array('pay_status'=>1,'pay_game_status'=>0))->select();
		$type = 102;
		if ($list[0]) {

			$list = D('check')->dealWithCheckList($type,$list);

			if (empty($list[0])) {return '';}

			foreach ($list as $k => $v) {
				$data[$k]['info'] = '玩家:'.$v['user_account'].',订单:'.$v['pay_order_number'].',操作:补单失败';
				$data[$k]['type'] = $type;
				$data[$k]['url'] = U('Spend/lists',array('pay_order_number'=>$v['pay_order_number']));
				$data[$k]['create_time'] = time();
				$data[$k]['status']=0;
				$data[$k]['position'] = $v['id'];
			}
			return $data;
		}else {
			D('check')->dealWithCheckListOnNull($type);
			return '';
		}

	}


	/**
	 * 统计总流水
	 * @param  array    $where      条件数组
	 * @return integer  数量
	 * @author 鹿文学
	 */
	public function totalAmount($map=array()) {

		$map['pay_status'] = 1;

		$sum = $this->where($map)->sum('pay_amount');

		return $sum?$sum:0;

	}


	/**
	 * 分组统计流水
	 * @param  array    $map        条件数组
	 * @param  string   $fieldname  字段别名
	 * @param  string   $group      分组字段名
	 * @param  integer  $flag   		时间类别(1:天,2:月,3:周)
	 * @return array       详细数据
	 * @author 鹿文学
	 */
	public function totalAmountByGroup($map=array(),$fieldname='amount',$group='time',$flag=1,$order='time') {

		switch($flag) {
			case 2:{$dateform = '%Y-%m';};break;
			case 3:{$dateform = '%Y-%u';};break;
			case 4:{$dateform = '%Y';};break;
			case 5:{$dateform = '%Y-%m-%d %H';};break;
			default:$dateform = '%Y-%m-%d';
		}

		$map['pay_status']=1;


		$data = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)

					->where($map)->group($group)->order($order)->select();

		return $data;
	}

	/**
	 * 分组统计所有流水
	 * @param  array    $map        条件数组
	 * @param  string   $fieldname  字段别名
	 * @param  string   $group      分组字段名
	 * @param  integer  $flag   		时间类别(1:天,2:月,3:周)
	 * @return array       详细数据
	 * @author 鹿文学
	 */
	public function allAmountByGroup($map=array(),$fieldname='amount',$group='time',$flag=1,$order='time') {

		switch($flag) {
			case 2:{$dateform = '%Y-%m';};break;
			case 3:{$dateform = '%Y-%u';};break;
			case 4:{$dateform = '%Y';};break;
			case 5:{$dateform = '%Y-%m-%d %H';};break;
			default:$dateform = '%Y-%m-%d';
		}

		$map['pay_status']=1;

		$union = D('deposit')->field('pay_order_number,FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)

				->where(['create_time'=>$map['pay_time'],'pay_status'=>1])

				->group($group)->select(false);


		$bind = M('Bind_recharge','tab_')->field('pay_order_number,FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',sum(real_amount) as '.$fieldname)

				->where(['create_time'=>$map['pay_time'],'pay_status'=>1])

				->group($group)->select(false);


		$sql = $this->field('pay_order_number,FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',sum(pay_amount) as '.$fieldname)

					->union('('.$union.')')

					->union('('.$bind.')')

					->where($map)->group($group)->select(false);

		$data = $this->table('('.$sql.') as a')->field('a.'.$group.',sum(a.'.$fieldname.') as '.$fieldname)->group('a.'.$group)->order($order)->select();

		return $data;
	}

	/*
	 * 付费用户
	 * @param  array    $map        条件数组
	 * @param  string   $fieldname  字段别名
	 * @param  string   $group      分组字段名
	 * @param  integer  $flag   		时间类别(1:天,2:月,3:周)
	 * @return array       详细数据
	 * @author 鹿文学
	 */
	public function totalPlayerByGroup($map=array(),$fieldname='count',$group='time',$flag=1,$order='time') {

		switch($flag) {
			case 2:{$dateform = '%Y-%m';};break;
			case 3:{$dateform = '%Y-%u';};break;
			case 4:{$dateform = '%Y';};break;
			case 5:{$dateform = '%Y-%m-%d %H';};break;
			default:$dateform = '%Y-%m-%d';
		}

		$map['pay_status']=1;


		$data = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',count( DISTINCT user_id) as '.$fieldname)

					->where($map)->group($group)->order($order)->select();

		return $data;

	}

	/*
	 * 付费用户
	 * @param  integer    $start    开始时间戳
	 * @param  integer    $end      结束时间戳
	 * @param  string   $fieldname  字段别名
	 * @param  string   $group      分组字段名
	 * @param  integer  $flag   		时间类别(1:天,2:月,3:周)
	 * @return array       详细数据
	 * @author 鹿文学
	 */
	public function totalPlayerByTime($start,$end,$fieldname='count',$group='time',$flag=1,$order='time') {

		switch($flag) {
			case 2:{$dateform = '%Y-%m';};break;
			case 3:{$dateform = '%Y-%u';};break;
			case 4:{$dateform = '%Y';};break;
			case 5:{$dateform = '%Y-%m-%d %H';};break;
			default:$dateform = '%Y-%m-%d';
		}

		$map['pay_status']=1;

		$map['create_time'] = ['between',[$start,$end]];

		$bindrecharge_data = M('bind_recharge','tab_')->field('FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')
				->where($map)->group($group)->select(false);

		$deposit_data = M('deposit','tab_')->field('FROM_UNIXTIME(create_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')
				->where($map)->group($group)->select(false);

		$map['pay_way'] = array('gt',0);
		unset($map['create_time']);
		$map['pay_time'] = ['between',[$start,$end]];

		$lists = $this->field('FROM_UNIXTIME(pay_time,"'.$dateform.'") as '.$group.',GROUP_CONCAT( DISTINCT user_id) as user_id')

					->union(' ('.$bindrecharge_data.') ')->union(' ('.$deposit_data.') ')

					->where($map)->group($group)->select(false);

		$lists = $this->field('a.'.$group.',GROUP_CONCAT(a.user_id) as user_id')->table(' ('.$lists.') as a')->group('a.'.$group)->order('a.'.$order)->select();

		$data = [];

		foreach($lists as $k=>$v) {
			$userid = array_unique(explode(',',$v['user_id']));
			$data[$k] = array(
				$group => $v[$group],
				$fieldname=>count($userid),
			);
		}

		return $data;

	}

	/*
	 * 付费用户总数
	 * @param  array    $map      条件数组
	 * @author 鹿文学
	 */
	public function player($map=array()) {

		$map['pay_status']=1;

		$data = $this->field('count( DISTINCT user_id) as count')

					->where($map)->select();

		return $data[0]?$data[0]['count']:0;

	}

	/*
	 * 付费总数
	 * @param  array    $map      条件数组
	 * @author 鹿文学
	 */
	public function amount($map=array()) {

		$map['pay_status'] = 1;

		$data = $this

			->where($map)->sum('pay_amount');


		return $data?$data:0;
	}

    /**
     * 列表
     *
     * @param int $p
     * @param array $map
     * @param bool $field
     *
     * @return mixed
     *
     * @author: 鹿文学[lwx]<fyj301415926@126.com>
     * @since: 2019\4\11 0011 13:40
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function lists($p=1, $map=array(), $order, $field=true)
    {

	    $page = intval($p);

	    $page = $page ? $page : 1; //默认显示第一页数据

        if(isset($_REQUEST['row'])) {
            $row = $_REQUEST['row'];
        } else {
            $row = 10;
        }
		$list = $this->field("tab_spend.*")
				->join("left join tab_promote as tp on tp.id = tab_spend.promote_id")
                ->where($map)
                ->page($page, $row)
                ->order($order?$order:'tab_spend.pay_time desc')
                ->select();

        $count = $this->where($map)->join("left join tab_promote as tp on tp.id = tab_spend.promote_id")->count();

        $data['data'] = $list;

        $page = set_pagination($count,$row);

        if($page) {
            $data['page']=$page;
        }

        return $data;
	}

    /**
     * 获取统计 $map,$page,$row
     */
    public function getSpendData($map=[],$field='',$group='',$order='',$page = 0,$row = 0) {
        if ($row == 0) {
            $data = $this->field($field)->where($map)->group($group)->order($order)->select();
        } else {
            $data = $this->field($field)->where($map)->page($page,$row)->group($group)->order($order)->select();
        }

        return $data;
    }

    public function sumSpend($map=[],$field='') {
        $sum = $this->where($map)->sum($field);

        return $sum;
    }


}