<?php
defined('IN_WEB') or die('Include Error!');
/**
 *	支付相关
 */
class ModelPayment
{

    const GGAMEID = 1; //创建订单时使用到的ggameid
    private $_status = 1;//订单下单成功状态码
    /**
     * 获取支付平台信息
     * @param array $param
     * @return int (0:其他平台,1:vivo,...)
     */
    private function getPlat($param) {
        if(empty($param['plat'])){
            return 0;
        }
        $plat = 0;
        switch($param['plat']) {
            case 'vivo':
                $plat = 1;
                break;
        }
        return $plat;
    }

    /**
     *	下单
     */
    public function createOrder($param){
        $data = array('code' => -1, 'orderId' => 0);
        if( !is_array($param) ){
            oo::logs()->debug3(["err"=>'param is not array',"param"=>$param],'paymant_err.log');
            return $data;
        }
        $plat       = $this->getPlat($param);
        $uid		= oo::functions()->uint($param['uid']);
        $sid 	    = oo::getDefinedSid($param['uid']);

        $gid 		= oo::functions()->uint($param['gid']);
        $ggameid    = self::GGAMEID;
        $orderTime 	= time();
        $orderId 	= empty($param['orderId']) ? $this->createOrderId($uid, $ggameid) : $param['orderId'];//vivo平台客户端自己上传orderId
        $gprice 	= $this->getGoodsPrice($gid,$uid);
        $flag       = oo::functions()->uint($param['flag']) ?? 0;
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        $levelId = oo::commonOprModel('member')->getUserLevel($uid)['levelId'];
        $table = otable::payment($uid);
        $serialNo = isset($param['serialNo']) ? $param['serialNo'] : '';
        $sql = "INSERT INTO {$table}(pid, siteuid, uid, sid, order_id, gid, order_time, pay_time, status,  pusd, flag, version,plat,platform_serial_num) VALUES( NULL, {$ggameid}, {$uid}, {$sid}, '{$orderId}', {$gid}, {$orderTime}, 0, 1, {$gprice}, {$flag}, '{$version}','{$plat}', '{$serialNo}') ";
        oo::commonOprDb('payment')->query($sql);
        $insertID = oo::commonOprDb('payment')->insertID();
        if( !$insertID ){
            oo::logs()->debug3(["err"=>'insert is table payment err',"param"=>$param],'paymant_err.log');
            $data['code'] = -3;
            oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"error"=>"create or insert db table payment  err","sql"=>$sql],'payment_err.log');
            return $data;
        }
        //插入到订单汇总表
        $summaryTable = otable::summarylist();
        $summarySql = " INSERT INTO {$summaryTable} (sl_orderid, sl_gid, sl_uid, sl_pay_time, sl_order_time, sl_pusd, sl_status, sl_sid, sl_levelId,sl_platform_serial_num) VALUES('{$orderId}', {$gid}, {$uid}, 0, {$orderTime}, {$gprice}, 1, {$sid},{$levelId},'{$serialNo}') ";
        oo::commonOprDb('payment')->query($summarySql);
        $insertIDsummary = oo::commonOprDb('payment')->insertID();
        if(!$insertIDsummary){
            oo::logs()->debug3(array("ts"=>time(),"uid"=>$param['uid'],"error"=>"create or insert db table summarylist err", 'sql' => $summarySql), 'payment_err.log');
        }
        $data['code'] = 1;
        $data['orderId'] = $orderId;
        $data['gid'] = $gid;
        return $data;
    }

    /**
     * 客户端上报发货验单异常的订单
     * @param array $param
     */
    public function createFailOrder($param){
        $uid      = oo::functions()->uint($param['uid']);
        $sid      = !empty($param['sid']) ? (int)$param['sid'] : oo::getDefinedSid($uid);
        $deviceid = oo::getDefinedDeviceId($uid, $sid);
        $serialNo = '0';
        switch ($deviceid) {
            case 2://IOS
                $serialNo  = isset($param['transactionId']) ? $param['transactionId'] : '0';
                $extraData = isset($param['extraData']) ? (array)json_decode(base64_decode(oo::functions()->escape($param['extraData'])),true) : [];
                $gid       = isset($extraData['gid']) ? $extraData['gid'] : 0;
                break;
            default://ANDROID
                $signedData = empty($param['signedData']) ? '[]' : base64_decode($param['signedData']);
                $signedData = (array)json_decode($signedData, true);
                $serialNo   = empty($signedData['orderId']) ? '0' : $signedData['orderId'];
                $orderInfo  = empty($signedData['developerPayload']) ? [] :  json_decode(base64_decode($signedData['developerPayload']),true);
                $gid = empty($orderInfo['gid']) ? 0 : $orderInfo['gid'];
                if(empty($gid) && isset($param['extraData'])){
                    $extraData = (array)json_decode(base64_decode(oo::functions()->escape($param['extraData'])),true);
                    $gid = isset($extraData['gid']) ? $extraData['gid'] : 0;
                }
                break;
        }

        //uid为0或gid为0的上报记录写文件
        if(empty($uid) || empty($gid)){
            oo::logs()->debug3([
                "err"=>'gid or uid empty', 'uid' => $uid, 'gid' => $gid, 'param'=>$param
            ],'paymentfail_err.log');
        }

        $data = array('code' => -1, 'orderId' => 0);
        if( !is_array($param) ){
            oo::logs()->debug3(["err"=>'param is not array',"param"=>$param],'paymentfail_err.log');
            return $data;
        }
        $plat       = $this->getPlat($param);
        $ggameid    = self::GGAMEID;
        $orderTime 	= time();
        //vivo平台客户端自己上传orderId
        $orderId 	= empty($param['orderId']) ? $this->createOrderId($uid, $ggameid) : $param['orderId'];
        $gprice 	= $this->getGoodsPrice($gid,$uid);
        $flag       = oo::functions()->uint($param['flag']) ?? 0;
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        $sku = empty($param['sku']) ? '' : $param['sku'];

        //解析到了订单信息
        if(strpos($serialNo, 'GPA') !== false){
            $table = otable::summarylist();
            $sql = "INSERT INTO {$table}(id,sl_uid, sl_sid, sl_orderid, sl_gid, sl_order_time, sl_platform_serial_num, sl_status, sl_pusd) VALUES( NULL, {$uid}, {$sid}, '{$orderId}', {$gid}, {$orderTime}, '{$serialNo}', 1, {$gprice}) ";
            oo::logs()->debug3(["msg"=>'save unexpected order',"sql"=>$sql],'paymentfail_err');
        }else{
            $table = otable::paymentFail($uid);
            $sql = "INSERT INTO {$table}(pid, siteuid, uid, sid, order_id, gid, order_time, platform_serial_num, status,  pusd, flag, version,plat, sku) VALUES( NULL, {$ggameid}, {$uid}, {$sid}, '{$orderId}', {$gid}, {$orderTime}, '{$serialNo}', 1, {$gprice}, {$flag}, '{$version}','{$plat}', '{$sku}') ";
        }
        oo::commonOprDb('payment')->query($sql);

        $insertID = oo::commonOprDb('payment')->insertID();
        if( !$insertID ){
            oo::logs()->debug3(["err"=>'insert is table payment_fail err',"param"=>$param],'paymentfail_err');
            $data['code'] = -3;
            oo::logs()->debug3(["uid"=>$param['uid'],"error"=>"create or insert db table payment_fail err","sql"=>$sql],'paymentfail_err');
            return $data;
        }
        $data['code']    = 1;
        $data['orderId'] = $orderId;
        $data['gid']     = $gid;
        return $data;
    }

    /**
     *	生成唯一订单号
     */
    protected function createOrderId($uid = 0, $ggameid = 0)
    {
        return date('YmdHis').$uid.$ggameid.substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }

    /**
     *	获取商品的美元值
     */
    public function getGoodsPrice($gid = 0,$uid=0)
    {
        if(in_array($gid,[710,711,712])){//连环礼包
            if(oo::commonOprRedis('activity')->get(okeys::bindChainGift($uid))){
                $aid  = oo::commonOprRedis('activity')->get(okeys::bindChainGift($uid));
                $reward = oo::commonOprModel('activitynew')->getChainGiftConf($uid,$aid,$gid);
                return (float)$reward['priceNum'];
            }
        }
        if($gid>720&&$gid<=750){//超级连环礼包
            $version = oo::commonOprModel('user')->getUserVersion($uid);
            if(oo::compareVersion($version,'1.7.4')&&oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack($uid))){
                $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack($uid));
                $reward = oo::commonOprModel('activitynew')->getCGRewardByGid($uid,$aid,$gid);
                return (float)$reward['priceNum'];
            }
        }
        if($gid>750&&$gid<=760){//四选一活动礼包
            $reward = oo::commonOprModel('activitynew')->getEasterGiftBag($uid,$gid);
            return (float)$reward['priceNum'];
        }
        if($gid>760&&$gid<=790){//超级连环礼包2
            $version = oo::commonOprModel('user')->getUserVersion($uid);
            if(oo::compareVersion($version,'1.10.1')&&oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack2($uid))){
                $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack2($uid));
                $reward = oo::commonOprModel('activitynew')->getCGRewardByGid($uid,$aid,$gid);
                return (float)$reward['priceNum'];
            }
        }
        //体力不足价格按积分变化
        if(in_array($gid, [1502])){
            if(oo::compareVersion(oo::commonOprModel('user')->getUserVersion($uid),'1.7.7')){
                $goodInfoTemp = oo::commonOprRedis('common')->get(okeys::shopNotEnoughLog($uid,$gid));
                $goodInfoTemp = json_decode($goodInfoTemp, true);
                if(!empty($goodInfoTemp)){
                    return (float)$goodInfoTemp['gprice'];
                }
            }
        }

        //
        if(in_array($gid, [1501,1511])){
            //金币、钻石不足价格按积分变化
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            $vipPoint = $userInfo['vipPoint'];//用户积分
            if($vipPoint < 1000){ //1000积分一下走旧逻辑
                $goodInfoTemp = oo::commonOprRedis('common')->get(okeys::shopNotEnoughLog($uid,$gid));
                $goodInfoTemp = json_decode($goodInfoTemp, true);
                if(!empty($goodInfoTemp)){
                    return (float)$goodInfoTemp['gprice'];
                }
            }
        }

        if(in_array($gid, [1810,1811])){
            //二选一
            $reward = oo::commonOprModel('activitynew')->getChooseOneGoods($uid);
            if($reward){
                foreach($reward as $row){
                    if($row['gid'] == $gid){
                        return (float)$row['priceNum'];
                    }
                }
            }
        }

        if(in_array($gid, [1837,1838])){
            //1+1
            $reward = oo::commonOprModel('activitynew')->getActivityGoods($uid,"one_plus_gift");
            if($reward){
                foreach($reward as $row){
                    if($row['gid'] == $gid){
                        return (float)$row['priceNum'];
                    }
                }
            }
        }

        if(in_array($gid, [1839,1840])){
            //惊喜礼包
            $reward = oo::commonOprModel('activitynew')->getActivityGoods($uid,"safe_surprise");
            if($reward){
                foreach($reward as $row){
                    if($row['gid'] == $gid){
                        return (float)$row['priceNum'];
                    }
                }
            }
        }
        $table = otable::goodsCrazy();
        $sql = "SELECT gprice FROM {$table} WHERE gid = $gid LIMIT 1";
        $ret = oo::commonOprDb('payment')->getOne($sql, MYSQLI_ASSOC);
        $gprice = empty($ret) ? 0 : $ret['gprice'];
        return $gprice;
    }

    /**
     * 发货
     */
    public function success($param)
    {
        $data = array('code' => -1);
        $uid = oo::functions()->uint($param['uid']);
        $channel = oo::functions()->uint($param['channel']);
        $sid = !empty($param['sid']) ? (int)$param['sid'] : oo::getDefinedSid($uid);
        $deviceid = oo::getDefinedDeviceId($uid, $sid);
        //判断设备类型
        switch ($deviceid) {
            case 2://IOS
                $data = oo::commonOprModel('paymentapple')->deliveryApplePay($param);
                break;
            default://ANDROID
                $data = oo::commonOprModel('paymentgoogle')->deliveryGooglePay($param);
                break;
        }
        return $data;
    }

    /**
     * 为多种支付方式提供公共入口
     */
    public function pubDelivery($uid = 0, $orderId = 0, $serialNo = 0)
    {
        return self::delivery($uid, $orderId, $serialNo);
    }

    /**
     * 多种支付方式的发货入库接口
     */
    protected function delivery($uid = 0, $orderId = 0, $serialNo = 0){
        if( empty($uid) || empty($orderId) ){
            return -1;
        }
        //查询订单状态,如果为已发货或退单则返回失败
        $tablePayment = otable::payment($uid);
        $sql = " SELECT gid, status, flag, uid, version, sid FROM {$tablePayment} WHERE  order_id = '{$orderId}' LIMIT 1 ";
        $paymentInfo = oo::commonOprDb('payment')->getOne($sql, MYSQLI_ASSOC);
        if( empty($paymentInfo) || !is_array($paymentInfo) ){
            oo::logs()->nodatedebug(array('code'=>-2,'uid' => $uid, 'orderId' => $orderId, 'paymentInfo' => $paymentInfo,'serialNo'=>$serialNo), 'payment_deliveryFail.log');
            return -2;
        }
        if(!isset($paymentInfo['uid']) || $uid != $paymentInfo['uid']){//如果该订单UID和发货的UID不一致
            return -5;
        }
        $flag = $paymentInfo['flag'] ?? 0;
        $version = $paymentInfo['version'] ?? '';
        $sid = $paymentInfo['sid'] ?? 0;

        //订单状态不正确
        $status = $paymentInfo['status'];
        if( $status != $this->_status ){
            oo::logs()->nodatedebug(array('uid' => $uid, 'orderId' => $orderId, 'status' => $status, 'line' => __LINE__ ,'serialNo'=>$serialNo), 'payment_deliveryFail.log');
            return -3;
        }

        //更新订单状态
        $payTime = time();
        $sqlUpdate = "UPDATE {$tablePayment} SET status = 2, pay_time = {$payTime}, platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' LIMIT 1";
        $retQuery = oo::commonOprDb('payment')->query($sqlUpdate);

        //正式发奖
        $gid = $paymentInfo['gid'];//商品ID
        $retReward = $this->reward($uid, $gid, $flag, $version, $sid);
        if( !$retReward ){
            oo::logs()->debug3(array('uid' => $uid, 'orderId' => $orderId, 'gid' => $gid, 'line' => __LINE__,'serialNo'=>$serialNo ), 'payment_retRewardFail.log');
            return -4;
        }

        //更新订单汇总表
        $table = otable::summarylist();
        $sqlUpdateSummary = " UPDATE {$table} SET sl_status = 2, sl_pay_time = {$payTime} WHERE sl_uid = {$uid} AND sl_orderid = '{$orderId}' LIMIT 1";
        oo::commonOprDb('payment')->query($sqlUpdateSummary);

        return true;
    }

    /**
     * 是否有购买记录
     * @param int $uid
     * @return bool
     * Created by: Owen
     * Created on: 2020/8/17 14:22
     */
    public function checkBought($uid = 0)
    {
        $uid = oo::functions()->uint($uid);
        $key = okeys::bought($uid);
        $cacheBought = intval(oo::commonOprRedis('common')->get($key));
        if( $cacheBought === 1 ){
            return  true;
        }
        $table = otable::payment($uid);
        $sql = "SELECT pid FROM {$table} WHERE uid = {$uid} AND status = 2 LIMIT 1 ";
        $ret = oo::commonOprDb('payment')->getOne($sql, MYSQLI_ASSOC);
        $bought = false;
        if( !empty($ret) ){
            $bought = true;
            $saveCache = 1;
            oo::commonOprRedis('common')->setex($key, $saveCache,86400*7);
        }
        return $bought;
    }

  	/**
     * 支付
     * @param $param
     * @param $newVersion
     * @return false|string
     * Created by: Owen
     * Created on: 2019/11/14 18:19
     */
    public function payment($param,$newVersion = false){
        $uid     = oo::functions()->uint($param['uid']);
        $orderId = oo::functions()->escape($param['orderId']);
        $paymenttb = otable::payment($uid);
        $sid = !empty($param['sid']) ? (int)$param['sid'] : oo::getDefinedSid($uid);
        $deviceid = oo::getDefinedDeviceId($uid, $sid);
        if($param['signature'] != 'fakesignature'){
            switch ($deviceid) {
                case 2://IOS
                    $orderInfo = oo::commonOprModel('paymentapple')->crazyGodDeliveryApplePay($param);
                    if($orderInfo['status'] == 2){
                        return json_encode(['code'=>1,'msg'=>'order reward was given','err'=>1]);
                    }
                    $serialNo = $orderInfo['transaction_id'];
                    break;
                default://ANDROID
                    $sql = "SELECT * FROM {$paymenttb} WHERE uid={$uid} AND order_id='{$orderId}' LIMIT 1";
                    $orderInfo = oo::commonOprDb('payment')->getOne($sql,1);
                    if(empty($orderInfo)){
                        return json_encode(['code'=>-2,'msg'=>'order error','err'=>2]);
                    }
                    if($orderInfo['status'] == 2){
                        return json_encode(['code'=>1,'msg'=>'order reward was given','err'=>3]);
                    }
                    /**plat > 0表示andor外的三方支付(vivo,已在外层验证过) **/
                    if(empty($orderInfo['plat'])){
                        $ret = oo::commonOprModel('paymentgoogle')->validateGooglePay($param);//验证失败
                    }else{
                        $ret = $this->checkPlatOrder($param);
                    }
                    if( !$ret ){
                        return json_encode(['code'=>-3,'msg'=>'Google sign error','err'=>4]);
                    }
                    $signedData = base64_decode($param['signedData']);
                    $signedData = json_decode($signedData, true);
                    if( !is_array($signedData) ){
                        return json_encode(['code'=>-4,'msg'=>'signedData error','err'=>5]);
                    }
                    if(!$newVersion){
                        $orderId = $signedData['extraData'];//订单ID
                    }
                    $productId = $signedData['productId'];//商品ID
                    $serialNo = $signedData['orderId'] ?? 0;//谷歌支付的流水号
                    break;
            }
        }else{
            $sql = "SELECT * FROM {$paymenttb} WHERE uid={$uid} AND order_id='{$orderId}' LIMIT 1";
            $orderInfo = oo::commonOprDb('payment')->getOne($sql,1);
            if(empty($orderInfo)){
                return json_encode(['code'=>-2,'msg'=>'order error','err'=>6]);
            }
            if($orderInfo['status'] == 2){
                return json_encode(['code'=>1,'msg'=>'order reward was given','err'=>7]);
            }
            //更新订单为测试订单
            $table = otable::summarylist();
            $sqlUpdateSummary = " UPDATE {$table} SET sl_sid = -1 WHERE sl_uid = {$uid} AND sl_orderid = '{$orderId}' LIMIT 1";
            oo::commonOprDb('payment')->query($sqlUpdateSummary);
        }
        $order_scene_father = "其它";
        $order_scene_son    = "其它";
        $gid = intval($orderInfo['gid']);
        $tb  = otable::goodsCrazy();
        $sql = "SELECT * FROM {$tb} WHERE gid={$gid}";
        $goodInfo = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        $time    = time();
      	$free    = false;
        $version = oo::commonOprModel('user')->getUserVersion($uid);
        $isPush  = false;
        $AssetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $propsArr= [];
        if($gid>=710&&$gid<=760){//特殊商品不固定价格则更改价格(连环礼包,超级连环礼包,四选一活动礼包)
            $gprice 	= $this->getGoodsPrice($gid,$uid);
            $newPusd = $goodInfo['gprice'] = $gprice;
        }
        if(in_array($gid, [1501,1502,1511])){
            $gprice 	= $this->getGoodsPrice($gid,$uid);
            $goodInfo['gprice'] = $gprice;
        }
        if(in_array($gid, [1810,1811,1837,1838,1839,1840])){
            $gprice 	= $this->getGoodsPrice($gid,$uid);
            $newPusd = $goodInfo['gprice'] = $gprice;
        }
        if($goodInfo['gtype'] ==1){
            $gbaseReward = intval($goodInfo['gbaseReward']);
            //商城默认走体力优惠券逻辑
            ////////////////////////////////
            $param['shopDiscount'] = 1;
            if(empty($param['shopDiscount'])){
                if(oo::commonOprModel('newvip')->checkNewVip($uid)){
                    $config = oo::commonOprModel('newvip')->getUserVipLv($uid,true,false,155);
                    $gbaseReward = ceil($gbaseReward + $gbaseReward*$config['shopAppend']);
                }
                $tips = "";
                if(oo::commonOprRedis("common")->ttl(okeys::PropsExpire($uid,"37-spins")) > 0){
                    $gbaseReward = 2 * $gbaseReward;
                    $tips = "【首冲限时优惠券】";
                    oo::commonOprRedis("common")->delete(okeys::PropsExpire($uid,"37-spins"));
                }
                oo::commonOprModel('member')->optProperty($uid,['spins'=>$gbaseReward],'+',310,'商城购买获取体力:'.$orderId.$tips);
            }else{
                //商城促销活动
                $tips = "【商城限时优惠券】";
                $activityConfig = oo::commonOprModel('activitynew')->activityLock($uid, 'shop_promotion', true);
                $vipAddBet = 0;
                if(oo::commonOprModel('newvip')->checkNewVip($uid)){
                    $config = oo::commonOprModel('newvip')->getUserVipLv($uid,true,false,155);
                    $vipAddBet = empty($config['shopAppend']) ? 0 : $config['shopAppend'];
                }
                if($activityConfig){
                    $point = oo::commonOprModel('newvip')->getUserCurPoint($uid);
                    if(!empty($activityConfig['activityData']['config']['init']) && is_array($activityConfig['activityData']['config']['init'])){
                        $bet = 0;
                        foreach($activityConfig['activityData']['config']['init'] as $row){
                            if($point < $row['point']){
                                $bet = $row['bet'];
                                break;
                            }
                        }
                        $gbaseReward = (1 + $bet + $vipAddBet) * $gbaseReward;
                        oo::logs()->debug5(['uid'=>$uid,'商城促销'=>'加倍'.$bet,'time'=>time()],date('Ymd').'.log','shopPromotion/');
                    }
                    oo::commonOprModel('statistics')->shopDiscountSta($uid,$goodInfo['gprice']);//商城促销统计
                    oo::commonOprRedis('common')->hIncrBy(okeys::ShopPromotionBuyNumber(),$uid,1);
                }else{
                    $gbaseReward = ceil($gbaseReward + $gbaseReward*$vipAddBet);
                    if(oo::commonOprRedis("common")->ttl(okeys::PropsExpire($uid,"37-spins")) > 0){
                        $gbaseReward = 2 * $gbaseReward;
                        $tips = "【首冲限时优惠券】";
                        oo::commonOprRedis("common")->delete(okeys::PropsExpire($uid,"37-spins"));
                    }
                }
                oo::commonOprModel('member')->optProperty($uid,['spins'=>$gbaseReward],'+',310,'商城购买获取体力:'.$orderId.$tips);
            }
//            oo::commonOprModel('activitynew')->addCommonScore($uid,'spins_master',intval($gbaseReward));
            $data['data']=['spins'=>$gbaseReward,'gtype'=>1];
            $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_SPINS,['num'=>$gbaseReward]);
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $propsArr[] = ["propsId"=>15,"num"=>$gbaseReward];
            $order_scene_father = "商城";
            $order_scene_son    = "商城:体力";
        }
        else if($goodInfo['gtype'] ==2){
            $property = oo::commonOprModel('member')->getUserAssetsInfo($uid);
            $level = intval($property['levelId']);
            $tb = otable::goodsCoin();
            $sql = "SELECT * FROM {$tb} WHERE gsku='{$goodInfo['gsku']}' AND levelId={$level}";
            $coinInfo = oo::commonOprDb('payment')->getOne($sql,1);
            $gbaseReward = intval($coinInfo['num']);
            //商城促销活动
            if(!empty($param['shopDiscount'])){
                $tips = "【商城限时优惠券】";
                $activityConfig = oo::commonOprModel('activitynew')->activityLock($uid, 'shop_promotion', true);
                if($activityConfig){
                    $point = oo::commonOprModel('newvip')->getUserCurPoint($uid);
                    if(!empty($activityConfig['activityData']['config']['init']) && is_array($activityConfig['activityData']['config']['init'])){
                        $bet = 0;
                        foreach($activityConfig['activityData']['config']['init'] as $row){
                            if($point < $row['point']){
                                $bet = $row['bet'];
                                break;
                            }
                        }
                        $gbaseReward = (1 + $bet) * $gbaseReward;
                        oo::logs()->debug5(['uid'=>$uid,'商城促销'=>'加倍'.$bet,'time'=>time()],date('Ymd').'.log','shopPromotion/');
                    }
                }
                oo::commonOprModel('member')->optProperty($uid,['money'=>$gbaseReward],'+',310,'商城购买获取金币:'.$orderId.$tips);
                oo::commonOprModel('statistics')->shopDiscountSta($uid,$goodInfo['gprice']);//商城促销统计
                oo::commonOprRedis('common')->hIncrBy(okeys::ShopPromotionBuyNumber(),$uid,1);
            }else{
                $tips = "";
                if(oo::commonOprRedis("common")->ttl(okeys::PropsExpire($uid,"37-coins")) > 0){
                    $gbaseReward = 2 * $gbaseReward;
                    $tips = "【首冲限时优惠券】";
                    oo::commonOprRedis("common")->delete(okeys::PropsExpire($uid,"37-coins"));
                }
                oo::commonOprModel('member')->optProperty($uid,['money'=>$gbaseReward],'+',310,'商城购买获取金币:'.$orderId.$tips);
            }
            $data['data']=['money'=>$gbaseReward,'coins'=>$gbaseReward];
            $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_COINS,['num'=>$gbaseReward]);
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $propsArr[] = ["propsId"=>14,"num"=>$gbaseReward];
            $order_scene_father = "商城";
            $order_scene_son    = "商城:金币";
        }
        else if($goodInfo['gtype'] == 3 ){
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            if($goodInfo['gid'] == 306) { //每日礼包
                //每日宝箱
                $result = oo::commonOprModel('activitynew')->setDailyChestBuy($uid);
                $data['data'] = $result;
                $propsArr[] = ["propsId"=>19,"num"=>1,"value"=>$result['treasureChest']];
                $order_scene_father = "商城";
                $order_scene_son    = "商城:每日小丑宝箱";
            }else{
                oo::commonOprModel('props')->addUserProps($uid,$goodInfo['gimg'],1,0,310);
                $propsArr[] = $data['data']['props'][] = [
                    'propsId' => $goodInfo['gimg'],
                    'num'     => 1,
                    'value'   => 1,
                ];
            }
        }
        else if($goodInfo['gtype'] == 5 ){
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            oo::commonOprRedis('common')->setex(okeys::TpFeeTimes($uid),intval(oo::commonOprRedis('common')->get(okeys::TpFeeTimes($uid))) + 1, oo::todayDeadline());
            oo::commonOprRedis('common')->hSet(okeys::bigwheelPay($uid),$time,$orderId);
            $data['data']=['wheel'=>4];
            $order_scene_father = "转盘";
            $order_scene_son    = "转盘:黄金转盘";
        }
        else if($goodInfo['gtype'] == 6 ){
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            if($gid == 601){
                $coins = oo::commonOprModel('goods')->getGoodCoins($uid,'coins03');
                $coins = $coins * 0.5;
                $spins = intval($goodInfo['gbaseReward']);
                $diamond = 0;
                if(oo::compareVersion($version,'1.7.3')) {
                    if(!empty($goodInfo['goriginReward'])) {
                        $reward = json_decode($goodInfo['goriginReward'], true);
                        foreach ($reward as $p) {
                            $p['propsId'] == 22 && $diamond = $p['num'];
                            $p['propsId'] == 14 && $coins = $p['num'];
                        }
                    }
                }
                oo::commonOprModel('member')->optProperty($uid,['money'=>$coins,'spins'=>$spins,'diamond'=>$diamond],'+',304,'首充获取金币体力钻石');
            }else if($gid == 602){
                $spins = 0;
                $coins = 0;
                $diamond = 0;
                $reward = json_decode($goodInfo['gbaseReward'],true);
                foreach ($reward as $p){
                    $p['propsId'] == 14 && $coins = $p['num'];
                    $p['propsId'] == 15 && $spins = $p['num'];
                    $p['propsId'] == 22 && $diamond = $p['num'];
                }
                oo::commonOprModel('member')->optProperty($uid,['money'=>$coins,'spins'=>$spins,'diamond'=>$diamond],'+',304,'（新）首充获取金币体力钻石');
            }
            $data['data']=['spins'=>$spins, 'money'=>$coins, 'coins'=>$coins, 'diamond'=>$diamond];
            $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_SPINS,['num'=>$spins]);
            $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_COINS,['num'=>$coins]);
            $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_DIAMONDS,['num'=>$diamond]);
            oo::commonOprRedis('User')->setex(okeys::firstPay($uid,$gid),1,3*24*60*60);
            //首充优惠
            if(oo::compareVersion($version,"1.8.0")){
                $couponVer = oo::commonOprRedis('common')->get(okeys::firstPayCouponVersion());
                $couponVer = empty($couponVer) ? '1.9.1' : $couponVer; //1.9.1版本临时隐藏首冲优惠券商品
                if(!oo::compareVersion($version, $couponVer)){
                    $data['data']['coupon'] = oo::commonOprModel('props')->setFirstPayPromotion($uid);
                }
            }
            $propsArr[] = ["propsId"=>14,"num"=>$coins];
            $propsArr[] = ["propsId"=>15,"num"=>$spins];
            $order_scene_father = "礼包";
            $order_scene_son    = "礼包:首充";
        }
        else if($goodInfo['gtype'] == 7){
            if(in_array($goodInfo['gid'],[710,711,712])){
                if(oo::commonOprRedis('activity')->get(okeys::bindChainGift($uid))){
                    $aid  = oo::commonOprRedis('activity')->get(okeys::bindChainGift($uid));
                    $reward = $this->sendGift($uid,$aid,$goodInfo['gid']);
                    if(is_array($reward)){
                        $data['data']['treasureChest'] = $reward['treasureChest'];
                    }else{
                        $reward = [];
                    }
                }else{
                    $reward = json_decode($goodInfo['gbaseReward'],true);
                    $coin   = oo::commonOprModel('goods')->getGoodCoins($uid,$reward['coins']['coins']) * $reward['coins']['bet'];
                    oo::commonOprModel('member')->optProperty($uid,['money'=>$coin,'spins'=>$reward['spins']],'+',311,$goodInfo['gdesc']);
                    foreach ($reward['props'] as $row){
                        oo::commonOprModel('props')->addUserProps($uid,$row['propsId'],$row['num'],0,311);
                    }
                    $cacheKey = okeys::SerialPackTimer($uid,$gid);
                    oo::commonOprRedis('common')->hIncrBy(okeys::SerialPackTimer(),$cacheKey,1);
                }
                $data['data']['props'] = $reward['props'];
                array_push($reward['props'],["propsId"=>14,"num"=>$reward['coin']],["propsId"=>15,"num"=>$reward['spin']]);
                $propsArr  = $reward['props'];
                $order_scene_father = "礼包";
                $order_scene_son    = "礼包:连环礼包";
            }else{
                $giftArr = oo::commonOprModel('goods')->getGiftConfig();
                $reward = $giftArr[$gid];
                $money  = intval(oo::commonOprModel('goods')->getGoodCoins($uid,$reward['coins']) * $reward['coinsBet']);
                $diamond = 0;
                if(oo::compareVersion($version,'1.7.3')) {
                    if(!empty($goodInfo['goriginReward'])) {
                        $goriginReward = json_decode($goodInfo['goriginReward'], true);
                        foreach ($goriginReward as $p) {
                            $p['propsId'] == 22 && $diamond = $p['num'];
                        }
                    }
                }
                $gbaseReward = intval($goodInfo['gbaseReward']);
                $data['data']=[
                    'spins'=>$gbaseReward,
                    'money'=>$money,
                    'coins'=>$money,
                    'diamond'=>$diamond,
                ];
                oo::commonOprModel('member')->optProperty($uid,$data['data'],'+',300,$goodInfo['gdesc']);
                $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_SPINS,['num'=>$gbaseReward]);
                $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_COINS,['num'=>$money]);
                $isPush && oo::commonOprModel('Workerman')->push($uid,ocmd::$SVR_UPDATE_DIAMONDS,['num'=>$diamond]);
                if(in_array($gid,[701,702,703])){
                    oo::commonOprRedis('common')->incr(okeys::promotion($uid,$gid>701?$gid:""));
                    oo::commonOprRedis('common')->expire(okeys::promotion($uid,$gid>701?$gid:""),oo::todayDeadline());
                }
                $propsArr[] = ["propsId"=>14,"num"=>$money];
                $propsArr[] = ["propsId"=>15,"num"=>$gbaseReward];
                $order_scene_father = "礼包";
                $order_scene_son    = "礼包:充值+限时+常规";
            }
          	$sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
        }
        else if($goodInfo['gtype'] == 8){
          	$sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
          	switch ($deviceid){
                case 2:
                    $serialNo = $orderInfo['original_transaction_id'];
                    $expire = ceil($orderInfo['expires_date_ms']/1000);
                    oo::commonOprModel('newvip')->setVip($uid,$expire,$orderInfo['original_transaction_id']);
                break;
                default:
                    $packageName   = $signedData['packageName'];//订单ID
                    $purchaseToken = $signedData['purchaseToken'] ?? 0;//谷歌支付的流水号
                    $purchaseInfo  = oo::commonOprModel('Paymentgoogle')->getUserSubscribeStatus($packageName,$productId,$purchaseToken);
                    $expire        = ceil($purchaseInfo['expiryTimeMillis']/1000);
                    oo::commonOprModel('newvip')->setVip($uid,$expire,$purchaseToken);
                break;
            }
            oo::logs()->debug3(["ts"=>time(),"uid"=>$uid,"param"=>$param,"sid"=>$deviceid,"orderInfo"=>$orderInfo],'payment_add_vip.log');
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            if($gid == 801 && $userInfo['vip_expire'] == 0){
                $free = true;
                $sql  = "UPDATE {$paymenttb} SET pusd = 0,status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            }
            oo::commonOprRedis('common')->delete(okeys::VipExperience($uid));
            oo::commonOprModel('Workerman')->push($uid,ocmd::$send['Vip_Rec'],['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);
            //购买vip取消跑马灯
            //oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"buyVip"]);//异步跑马灯消息
            $order_scene_father = "会员";
            $order_scene_son    = "会员:开通订阅";
            oo::commonOprModel('ta')->setEventData($uid,'user_set',["is_member"=>1,"member_time"=>$expire]);
        }
        else if($goodInfo['gtype'] == 9){
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            $reward = json_decode($goodInfo['gbaseReward'],true);
            foreach ($reward as $row){
                if($row['type'] == 1){
                    oo::commonOprModel('member')->optProperty($uid,['money'=>$row['num']],'+',305,'节日礼包');
                    $data['data']['coins'] = $data['data']['money'] = $row['num'];
                    $propsArr[] = ["propsId"=>14,"num"=>$row['num']];
                }else if($row['type'] == 2){
                    oo::commonOprModel('member')->optProperty($uid,['spins'=>$row['num']],'+',305,'节日礼包');
                    $data['data']['spins'] = $row['num'];
                    $propsArr[] = ["propsId"=>15,"num"=>$row['num']];
                }else if($row['type'] == 3){
                    oo::commonOprModel('props')->addUserProps($uid,$row['id'],$row['num'],0,305);
                    $propsArr[] = ["propsId"=>$row['id'],"num"=>$row['num']];
                    $data['data']['card'] = [];
                }else if($row['type'] == 4){
                    $data['data']['festival'] = oo::commonOprModel('activity')->updateHolidayCollect($uid,$row['num']);
                }
            }
            oo::commonOprRedis('User')->hIncrBy(okeys::GoodBuyNum(),$uid.'_'.$gid,1);
            $order_scene_father = "弃用";
            $order_scene_son    = "弃用:节日礼包";
        }
        else if($goodInfo['gtype'] == 10){
            $endUseTime = time();
            $sql = "SELECT * FROM {$paymenttb} WHERE uid={$uid} AND gid={$gid} AND status=2 AND buff>{$endUseTime} ORDER BY buff DESC LIMIT 1";
            $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
            if(!empty($ret)){
                $buff = $ret['buff'] + 30*24*60*60;
            }else{
                if(oo::commonOprRedis('User')->get(okeys::SignInToday($uid))){
                    $buff = strtotime("23:59:59") + 30*24*60*60;
                }else{
                    $buff = strtotime("23:59:59") + 29*24*60*60;
                }
            }
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}',buff='{$buff}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            $reward = json_decode($goodInfo['gbaseReward'],true);
            if($reward['base']['type'] == 1){
                $type = 'money';
                $data['data']['coins'] = $reward['base']['num'];
            }else if($reward['base']['type'] == 2){
                $type = 'spins';
            }
            oo::commonOprModel('member')->optProperty($uid,[$type=>$reward['base']['num']],'+',330,'体力月卡');
            oo::commonOprRedis('usercache')->delete(okeys::SpinMonthly($uid,$gid));
            $data['data'][$type] = $reward['base']['num'];
            $data['data']['expire'] = $buff;
            $type == 'money' && $propsArr[] = ["propsId"=>14,"num"=>$reward['base']['num']];
            $type == 'spins' && $propsArr[] = ["propsId"=>15,"num"=>$reward['base']['num']];
            $order_scene_father = "弃用";
            $order_scene_son    = "弃用:体力月卡";
        }
        else if($goodInfo['gtype'] == 11){
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id='{$orderId}' AND status = 1 LIMIT 1";
            oo::commonOprRedis('usercache')->delete(okeys::CardBless($uid,$gid));
            $order_scene_father = "弃用";
            $order_scene_son    = "弃用:卡片祝福";
        }
        else if($goodInfo['gtype'] == 12){
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            $reward = json_decode($goodInfo['gbaseReward'],true);
            oo::commonOprModel('props')->addUserProps($uid,$reward['props'],$reward['num'],0,313);
            $propsArr[] = $data['data']['props'][] = [
                'propsId' => $reward['props'],
                'num'     => $reward['num'],
                'value'   => $reward['num'],
            ];
            $order_scene_father = "弃用";
            $order_scene_son    = "弃用:夺宝券";
        }
        else if($goodInfo['gtype'] == 13){
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            oo::commonOprModel('props')->addUserProps($uid,9,$goodInfo['gbaseReward'],0,313);
            $data['data']['props'][] = [
                'propsId' => 9,
                'num'     => $goodInfo['gbaseReward'],
                'value'   => $goodInfo['gbaseReward'],
            ];
            $data['data']['petFeed'] = $goodInfo['gbaseReward'];
            oo::commonOprModel('props')->addUserProps($uid,8,$goodInfo['goriginReward'],0,313);
            $data['data']['petExp'] = $goodInfo['goriginReward'];
            $data['data']['props'][] = [
                'propsId' => 8,
                'num'     => $goodInfo['goriginReward'],
                'value'   => $goodInfo['goriginReward'],
            ];
            $propsArr = $data['data']['props'];
            $order_scene_father = "商城";
            $order_scene_son    = "商城:宠物经验+粮食";
        }
        else if($goodInfo['gtype'] == 14){
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            oo::commonOprModel('props')->addUserProps($uid,8,$goodInfo['gbaseReward'],0,313);
            $propsAr[] = $data['data']['props'][] = [
                'propsId' => 8,
                'num'     => $goodInfo['gbaseReward'],
                'value'   => $goodInfo['gbaseReward'],
            ];
            $order_scene_father = "商城";
            $order_scene_son    = "商城:宠物经验";
        }
        else if($goodInfo['gtype'] == 15){
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            $vipPoint = $userInfo['vipPoint'];//用户积分
            $goodInfoTemp = oo::commonOprRedis('common')->get(okeys::shopNotEnoughLog($uid,$gid));
            if(($gid == 1502 || ($vipPoint < 1000 && in_array($gid, [1501, 1511]))) && !empty($goodInfoTemp)){
                $goodInfoTemp = json_decode($goodInfoTemp,1);
                $goodInfo['gbaseReward'] = $goodInfoTemp['gbaseReward'];
                $newPusd = $goodInfoTemp['gprice'];
                $goodInfo['gprice'] = $goodInfoTemp['gprice'];
                $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}',pusd={$newPusd} WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            }else{
                $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            }
            $order_scene_father = "不足";
            if(in_array($gid, [1501, 1503, 1504, 1505, 1506, 1507])){
                $property = oo::commonOprModel('member')->getUserAssetsInfo($uid);
                $level = intval($property['levelId']);
                $temp = json_decode($goodInfo['gbaseReward'],true);
                $coins= oo::commonOprModel('goods')->getGoodCoinsByLevelId($level + 1,$temp['coins']['coins']);
                $coins= $coins * $temp['coins']['bet'];
                oo::commonOprModel('member')->optProperty($uid,["money"=>$coins],'+',310,'商城购买获取金币');
                $data['data']=[ 'money'=>$coins, 'coins'=>$coins, ];
                $propsArr[] = ["propsId"=>14,"num"=>$coins];
                $order_scene_son    = "不足:金币不足";
            }else if($gid == 1502){
                oo::commonOprModel('member')->optProperty($uid,["spins"=>$goodInfo['gbaseReward']],'+',310,'商城购买获取体力');
                $data['data']=['spins'=>$goodInfo['gbaseReward']];
                $propsArr[] = ["propsId"=>15,"num"=>$goodInfo['gbaseReward']];
                $order_scene_son    = "不足:体力不足";
            }else if(in_array($gid, [1511, 1512, 1513, 1514, 1515, 1516])){
                oo::commonOprModel('member')->optProperty($uid,["diamond"=>$goodInfo['gbaseReward']],'+',312,'钻石不足购买');
                $data['data']=[ 'diamond'=>$goodInfo['gbaseReward'], ];
                $order_scene_son    = "不足:钻石不足";
            }
        }
        else if(in_array($goodInfo['gtype'],[16, 18, 19, 27])){//27为回归礼包
            $rid =$goodInfo['gtype']==27?454:311;
            if(in_array($gid, [1833,1834,1835,1836])){
                $rid = '314'; //超值礼包
            }
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid={$uid} AND order_id='{$orderId}' AND status=1 LIMIT 1";
            $reward = json_decode($goodInfo['gbaseReward'],true);
            $coin   = oo::commonOprModel('goods')->getGoodCoins($uid,$reward['coins']['coins']) * $reward['coins']['bet'];
            $diamond = 0;
            $crazyPassExp = 0;
            $data['data']['coins'] = $coin;
            $data['data']['money'] = $coin;
            $data['data']['spins'] = $reward['spins'];
            foreach ($reward['props'] as $key=>$row){
                if(in_array($row['propsId'],[19,20,21,29,30])){
                    $skin = isset($row['skin']) ? (int)$row['skin'] : 0;
                    $data['data']['treasureChest'] = oo::commonOprModel('props')->rewardChest($uid,$row['propsId'],'',$rid, $skin);
                }else if($row['propsId'] == 22){
                    $diamond = $row['num'];
                }else if($row['propsId'] == 38){
                    $crazyPassExp = $row['num'];
                }else{
                    $valueTemp = [];
                    if($row['propsId']==41 && !empty($row['skin'])){
                        $valueTemp["skin"] = $row['skin'];
                    }
                    oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'], $rid, "礼包:{$gid}",$valueTemp);
                }
                if(in_array($row['propsId'],[19,20,21,29,30])){
                    $propsArr[] = ["propsId"=>$row['propsId'],"num"=>1,"value"=>$data['data']['treasureChest']];
                }else{
                    $propsArr[] = ["propsId"=>$row['propsId'],"num"=>$row['num']];
                }
            }
            $data['data']['diamond'] = $diamond;
            $data['data']['crazyPassExp'] = $crazyPassExp;
            oo::commonOprModel('member')->optProperty($uid,['money'=>$coin,'spins'=>$reward['spins'],'diamond'=>$diamond],'+',$rid,$goodInfo['gdesc']);
            $data['data']['props'] = $reward['props'];
            $order_scene_father ="礼包";
            if ($goodInfo['gtype']==27){
                $order_scene_son = "礼包:召回礼包";
            }else if ($goodInfo['gtype']==16){
                $order_scene_son    = "礼包:规则礼包";
            }else if($goodInfo['gtype']==18){
                $order_scene_son    = "礼包:升级礼包";
            }else if($goodInfo['gtype']==19){
                $order_scene_son    = "礼包:金币老虎机礼包";
            }

        }
        else if($goodInfo['gtype'] == 17){
            if(self::payBet($uid,$orderId,false)){
                $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            }
            $order_scene_father ="支付加倍";
            $order_scene_son ="支付加倍:加倍";
        }
        else if($goodInfo['gtype'] == 20){
            $actInfo  = oo::commonOprModel('activitynew')->activityLock($uid,"traffic_permit",true);
            if(!empty($actInfo)){
                $aid = $actInfo['activityData']['aid'];
                $end = $actInfo['activityData']['end'];
                oo::commonOprRedis('activity')->setex(okeys::BuyTrafficPermitStatus($aid,$uid),1, max($end - time(),0));
                oo::async()->add('oo::commonOprModel("activitynew")->BuyTrafficPermitNotice',[$uid]);
            }else{
                $aid = 0;
            }
            if($gid == 1814){
                $expData = oo::commonOprModel('activitynew')->buyTrafficPermitLevelByPay($uid,15);
                $data['data']['props'][] = ['propsId'=>38,'num'=>$expData['actionNum'],'value'=>$expData['curNum']];
            }
            $sql = " UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}',buff='{$aid}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            oo::commonOprModel('activitynew')->buyTrafficPermitSta($uid);
            $order_scene_father = "通行证";
            $order_scene_son    = "通行证:开通";
        }
        else if($goodInfo['gtype'] == 21){ //钻石商品
            $reward = (int)$goodInfo['gbaseReward'];
            $data['data']['diamond'] = $reward;
            oo::commonOprModel('member')->optProperty($uid,['diamond'=>$reward],'+',310,'商城购买获得钻石:'.$reward);
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $order_scene_father = "商城";
            $order_scene_son    = "商城:钻石";
        }
        else if(in_array($goodInfo['gtype'],[22,28,29])){//超级连环礼包,彩蛋复活礼包,超级连环礼包2
            if($goodInfo['gtype']==22){
                $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack($uid));//超级连环礼包
            }else if($goodInfo['gtype']==28){
                $aid  = oo::commonOprModel('activitynew')->getBindActivity($uid,'easter_egg');//四选一活动
            }else if($goodInfo['gtype']==29){
                $aid  = oo::commonOprRedis('activity')->get(okeys::bindSuperSerialPack2($uid));//超级连环礼包2
            }
            if($aid){
                $reward = $this->sendReward($uid,$goodInfo['gid'],$aid);
                $data['data']['treasureChest'] = is_int($reward)||empty($reward)?[]:$reward['treasureChest'];
                $propsArr = $reward['props'];
                $goodInfo['gprice'] = (empty((float)$goodInfo['gprice'])) ? $this->getGoodsPrice($goodInfo['gid'], $uid) : $goodInfo['gprice'];
            }else{
                $reward['props'] =[];
            }
            $goodInfo['gsku'] = $reward['sku'];
            $data['data']['props'] = $reward['props'];
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $order_scene_father = "礼包";

            $order_scene_son    = $goodInfo['gtype']==22 ? "礼包:超级连环礼包" : ($goodInfo['gtype']==28?"礼包:彩蛋复活礼包":"礼包:超级连环礼包2");
        }
        else if($goodInfo['gtype'] == 23){
            //体力存钱罐
            $safeGoodsInfo = oo::commonOprModel('activitynew')->getActivityShopCache(okeys::activityShopCache($uid, 'spin_safe-'.$gid));
            if(empty($safeGoodsInfo)){
                $safeGoodsInfo = oo::commonOprModel('activitynew')->getSpinSafeGoodsByGid($uid, $gid);
            }
            if(!empty($safeGoodsInfo['price'])){
                $newPusd = $safeGoodsInfo['price'];
            }
            $gidTransForm = [1807=>2,1808=>3];
            $progressId   = $gidTransForm[$gid];
            $propsArr = $props = oo::commonOprModel('activitynew')->rewardSteelSafe($uid,$progressId,true);
            $data['data']['props'] = $props;
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $order_scene_father = "体力存钱罐";
            $order_scene_son    = "体力存钱罐:进度".$progressId;
        }
        else if($goodInfo['gtype'] == 24){
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            $expData = oo::commonOprModel('activitynew')->buyTrafficPermitLevelByPay($uid,[1809=>1,1815=>6,1816=>21][$gid]);
            $data['data']['props'][] = ['propsId'=>38,'num'=>$expData['actionNum'],'value'=>$expData['curNum']];
            $order_scene_father = "通行证";
            $order_scene_son    = "通行证:升级";
        }
        else if($goodInfo['gtype'] == 25 || $goodInfo['gtype'] == 30 || $goodInfo['gtype'] == 31){
            if($goodInfo['gtype'] == 30){
                $config = oo::commonOprModel('activitynew')->getActivityGoods($uid,"one_plus_gift");
                $logExplain = "购买1+1活动商品：";
                $reasonRid = 455;
            }else if($goodInfo['gtype'] == 31){
                $config = oo::commonOprModel('activitynew')->getActivityGoods($uid,"safe_surprise");
                $logExplain = "购买惊喜活动商品：";
                $reasonRid = 457;
            }else{
                $config = oo::commonOprModel('activitynew')->getChooseOneGoods($uid);
                $logExplain = "购买二选一活动商品：";
                $reasonRid = 120;
            }
            $data['data']['coins'] = 0;
            $data['data']['spins'] = 0;
            $data['data']['diamond']      = 0;
            $data['data']['crazyPassExp'] = 0;
            $data['data']['treasureChest']= [];
            $data['data']['goldCard']= [];
            if(!empty($config)){
                $gidPrices = array_column($config, 'priceNum', 'gid');
                $config = array_column($config,"props",'gid');
                $props  = $config[$gid];
                $newPusd = $gidPrices[$gid];

                foreach ($props as $key=>&$row){
                    $valueTemp = [];
                    if($row['propsId'] == 41 && !empty($row['value'])){
                        $valueTemp = $row['value'];
                    }
                    $info = oo::commonOprModel('member')->sendReward($uid, $row['propsId'], $row['num'],$reasonRid,$logExplain.$gid,$valueTemp,$row);
                    if(in_array($row['propsId'],[19,20,21,29,30])){
                        $data['data']['treasureChest'] = $info;
                    }else if($row['propsId'] == 22){
                        $data['data']['diamond'] = $row['num'];
                    }else if($row['propsId'] == 38){
                        $data['data']['crazyPassExp'] = $row['num'];
                    }else if($row['propsId'] == 14){
                        $data['data']['coins'] = $row['num'];
                    }else if($row['propsId'] == 15){
                        $data['data']['spins'] = $row['num'];
                    }else if($row['propsId'] == 13){
                        $data['data']['goldCard'] = is_array($info) ? $info : [$info];
                    }
                }
                $propsArr = $data['data']['props'] = $props;
            }

            if($goodInfo['gtype'] == 30){
                $aid  = oo::commonOprModel('activitynew')->activityLock($uid,"one_plus_gift");
                if($aid){
                    oo::commonOprRedis('Activity')->hSet(okeys::onePlusGiftBuyStatus($aid),$uid,1) ;//免费礼包
                    oo::commonOprRedis('activity')->hIncrBy(okeys::onePlusGiftBuyNum($aid),$uid,1);//累计
                    $goodInfo['gprice'] = (empty((float)$goodInfo['gprice'])) ? $this->getGoodsPrice($goodInfo['gid'], $uid) : $goodInfo['gprice'];
                }
                $order_scene_father = "礼包";
                $order_scene_son    = "礼包:1+1";
            }else if($goodInfo['gtype'] == 31){
                $aid  = oo::commonOprModel('activitynew')->activityLock($uid,"safe_surprise");
                if($aid){
                    oo::commonOprRedis('Activity')->hSet(okeys::safeSurpriseBuyStatus($aid),$uid,1) ;//免费礼包
                    $goodInfo['gprice'] = (empty((float)$goodInfo['gprice'])) ? $this->getGoodsPrice($goodInfo['gid'], $uid) : $goodInfo['gprice'];
                }
                $order_scene_father = "礼包";
                $order_scene_son    = "礼包:安全惊喜礼包";
            }else{
                $aid  = oo::commonOprModel('activitynew')->activityLock($uid,"choose_one");
                if($aid){
                    oo::commonOprRedis('Activity')->hSet(okeys::ChooseOneStatus($aid),$uid,1);
                    $goodInfo['gprice'] = (empty((float)$goodInfo['gprice'])) ? $this->getGoodsPrice($goodInfo['gid'], $uid) : $goodInfo['gprice'];
                }
                $order_scene_father = "礼包";
                $order_scene_son    = "礼包:二选一";
            }
            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}',buff='{$aid}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
        }
        else if($goodInfo['gtype'] == 26){
            $order_scene_father = "基金";
            if($gid==1812){ //首购
                $aid = oo::commonOprModel('activitynew')->activityLock($uid,"fund");
                if($aid){
                    oo::commonOprRedis("Activity")->setex(okeys::FundAid($uid),$aid,7 * 24 * 60 * 60);
                    oo::commonOprRedis("Activity")->hSet(okeys::FundAidUid($aid),$uid,time());
                    $data['data']['expire'] = time() + 7 * 24 * 60 * 60;
                }
                $order_scene_son    = "基金:首购";
            }else if($gid==1813){ //续购
                $aid = oo::commonOprRedis("Activity")->get(okeys::FundAid($uid));
                if($aid){
                    $ttl = oo::commonOprRedis("Activity")->ttl(okeys::FundAid($uid));
                    $ttl > 0 && oo::commonOprRedis("Activity")->expire(okeys::FundAid($uid),$ttl + 7 * 24 * 60 * 60);
                    $data['data']['expire'] = $ttl + 7 * 24 * 60 * 60 + time();
                }
                $order_scene_son    = "基金:续购";
            }else if($gid==1832){ //补签
                $aid = oo::commonOprRedis("Activity")->get(okeys::FundAid($uid));
                if($aid){
                    $actExtraData = json_decode($param['actExtraData'],true)??[];
                    !empty($actExtraData["fundBoomRepair"]) && oo::commonOprModel('activitynew')->setFundReissue($aid,$uid,$actExtraData["fundBoomRepair"]);
                    $data['data']['reissueList'] = oo::commonOprModel('activitynew')->getFundReissue($aid,$uid);
                }
                $order_scene_son    = "基金:补签";
            }

            $actGoodsTmp = oo::commonOprModel('activitynew')->getActivityShopCache(okeys::activityShopCache($uid, 'fund'));
            if($actGoodsTmp){
                $actGoods = array_column($actGoodsTmp, 'priceNum', 'gid');
                if(isset($actGoods[$gid])){
                    $newPusd = $actGoods[$gid];
                }
            }

            $sql = "UPDATE {$paymenttb} SET status = 2,pay_time={$time},use_time={$time},platform_serial_num = '{$serialNo}',buff='{$aid}' WHERE uid = {$uid} AND order_id = '{$orderId}' AND status = 1 LIMIT 1";
            oo::commonOprRedis('activity')->delete(okeys::BuyFundStatus($aid,$uid));
        }
        else{
            return json_encode(['code'=>-6,'err'=>8]);
        }
        oo::commonOprRedis('common')->setex(okeys::TodayBuyGoods($uid,$goodInfo['gtype']),1,oo::todayDeadline());
        oo::commonOprRedis('common')->setex(okeys::TodayBuyGoods($uid),1,oo::todayDeadline());
        oo::commonOprDb('payment')->query($sql);
        //更新订单汇总表
        $table = otable::summarylist();
        $sl_content = json_encode($data['data']);
        if($free){
            $sqlUpdateSummary = " UPDATE {$table} SET sl_pusd = 0 , sl_status = 2, sl_pay_time = {$time}, `sl_platform_serial_num`='{$serialNo}', sl_content = '{$sl_content}' WHERE sl_uid = {$uid} AND sl_orderid = '{$orderId}' LIMIT 1";
        }else{
            if(empty($newPusd)){
                $sqlUpdateSummary = " UPDATE {$table} SET sl_status = 2, sl_pay_time = {$time}, `sl_platform_serial_num`='{$serialNo}', sl_content = '{$sl_content}' WHERE sl_uid = {$uid} AND sl_orderid = '{$orderId}' LIMIT 1";
            }else{
                $sqlUpdateSummary = " UPDATE {$table} SET sl_status = 2, sl_pay_time = {$time}, `sl_platform_serial_num`='{$serialNo}',sl_pusd = {$newPusd}, sl_content = '{$sl_content}' WHERE sl_uid = {$uid} AND sl_orderid = '{$orderId}' LIMIT 1";
            }
        }
        oo::commonOprDb('payment')->query($sqlUpdateSummary);
        $data['code'] = 1;
        $sgsid = oo::getDefinedSid($uid);
        $data['data']['sku'] = ($sgsid==1)?$goodInfo['gsku']:str_replace('gworld.cc','astak.crazyspin',$goodInfo['gsku']);
        $data['data']['gid']   = $gid;
        $data['data']['price'] = floatval($goodInfo['gprice']);

        $data = self::goodDataTurnToFormat($data);

        $protectedTime = 300;
        oo::commonOprModel('member')->setUserStealProtect($uid,$protectedTime);
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['stealProtected'],[ 'expireTime' => time() + $protectedTime]);

        self::updateUserPayCache($uid,$gid,$goodInfo['gprice']);
        self::changeVipStatus($uid,$gid,$goodInfo['gprice'],$param['signature'] == 'fakesignature');

        //仅限: 商场体力(1)
        if(in_array($goodInfo['gtype'],[1]) && !empty($data['data']['spins'])){
            $data = self::payTurnTabBet($uid,$gid,$goodInfo['gprice'],$data);
        }
        /**
         * 排行榜活动期间支付记录 & 活动进度支付统计
         */
        $aid = oo::commonOprModel('activitynew')->activityLock($uid, 'rank');
        $aid && oo::commonOprRedis('activity')->hSetNx(okeys::ActivityBuyGoods($aid), $uid, 1);

        //锦标赛 + 超级收集活动 统计 & 活动进度支付统计
        oo::commonOprModel('statistics')->rankCollectSta($uid,$goodInfo['gprice'],$AssetsInfo['spins']);

        /**
         * 宝藏探索礼包 每次活动只能购买一次
         */
        if(in_array($gid,[1763,1764,1765,1766])){
            if(oo::compareVersion($version,'1.7.2')){
                $aid = oo::commonOprModel('activitynew')->activityLock($uid,"treasure");
            }else{
                $aid = 0;
            }
//            oo::commonOprRedis('activity')->hSet(okeys::treasureQuestGiftLog($aid), $uid, 1);
            oo::commonOprModel('activitynew')->setUserTreasureCacheLog($aid,$uid,"GiftPackBuyStatus",1);
        }
        if(oo::compareVersion($version,'1.7.0')){
            //累计充值活动
            oo::commonOprModel('activitynew')->addSumPayNum($uid,$goodInfo['gprice']);
            //邀请累计充值
            if(oo::compareVersion($version,'1.7.5')){
                oo::commonOprModel('invite')->addSumPayNum($uid,$goodInfo['gprice']);
            }
        }

        $isFirst = 1-intval(oo::commonOprModel('payment')->getUserPayTimes($uid)) == 0 ? true : false;
        $info = oo::commonOprModel('ta')->getPropsSSEventData($propsArr);
        oo::commonOprModel('ta')->setEventData($uid,"order_finish",[
            "order_id"=>$orderId,
            "order_scene_father"=>$order_scene_father,
            "order_scene_son"=>$order_scene_son,
            "shopid"=>$gid,
            "pay_method"=>$sgsid==1 ? "GOOGLE":"IOS",
            //"pay_amount"=>$data['data']['price'],
            "pay_amount"=>!empty($newPusd)?$newPusd:$data['data']['price'],
            "pay_reward_spin"=>$info['reward_spin'],
            "pay_reward_coin"=>$info['reward_coin'],
            "pay_reward_petfood"=>$info['reward_petfood'],
            "pay_reward_petexp"=>$info['reward_petexp'],
            "pay_reward_chest_list"=>empty($info['reward_chest_list'])?[]:$info['reward_chest_list'],
            "pay_reward_activity"=>$info['reward_activity'],
            "pay_reward_activity_time"=>$info['reward_activity_time'],
            "pay_reward_card_list"=>empty($info['reward_card_list'])?[]:$info['reward_card_list'],
            "pay_reward_card_joker"=>$info['reward_card_joker'],
            "is_first_pay"=> $isFirst,
        ]);

//        $props2 = $this->mergeOtherProps($data);
//        if($props2){
//            $data['data']['props2'] = $props2;
//        }
//        if(empty($data['data']['props'])){
//            unset($data['data']['props']);
//        }

        if($isFirst){
            $this->getUserFirstPayTS($uid,true);//更新首次支付时间
            oo::commonOprModel('ta')->setEventData($uid,'user_setOnce',["first_pay_time"=>time()]);
        }
        return json_encode($data);
    }

    public function mergeOtherProps($data) {
        if(empty($data['data'])){
            return [];
        }
        $props2 = empty($data['data']['props']) ? [] : $data['data']['props'];

        $propIds = array_column($props2, 'num','propsId');
        if(!empty($data['data']['coins']) && !isset($propIds[14])){
            $props2[] = ['propsId' =>14, 'num' => $data['data']['coins']];
        }
        if(!empty($data['data']['spins']) && !isset($propIds[15])){
            $props2[] = ['propsId' =>15, 'num' => $data['data']['spins']];
        }
        if(!empty($data['data']['crazyPassExp']) && !isset($propIds[38])){
            $props2[] = ['propsId' =>38, 'num' => $data['data']['crazyPassExp']];
        }
        if(!empty($data['data']['petFeed']) && !isset($propIds[9])){
            $props2[] = ['propsId' =>9, 'num' => $data['data']['petFeed']];
        }

        if(!empty($data['data']['petExp']) && !isset($propIds[8])){
            $props2[] = ['propsId' =>8, 'num' => $data['data']['petExp']];
        }
        if(!empty($data['data']['goldCard']) && !isset($propIds[13])){
            $props2[] = ['propsId' =>13, 'num' => $data['data']['goldCard']];
        }
        return $props2;
    }

    /**
     * 支付加倍转盘 发货
     * @param $param
     * @return false|string
     * Created by: Hss
     * Created on: 2020/7/21 17:54
     */
    public function payBet($uid,$orderId,$returnJson = true){
        //支付加倍逻辑
        $TurnPaybetLog = oo::commonOprRedis('common')->hGet(okeys::TurnPaybetLog(),$uid);
        if(!empty($TurnPaybetLog)){
            oo::commonOprRedis('common')->hDel(okeys::TurnPaybetLog(),$uid);//删除数据
            $TurnPaybetLog = json_decode($TurnPaybetLog,1);
            if($orderId == '免费' && $TurnPaybetLog['gid'] != 0){
                return ($returnJson?oo::response(-2,[],'支付加倍免费转盘 发货失败'):false);
            }
            if(!empty($TurnPaybetLog['reward']['spins'])){
                $gbaseReward = $TurnPaybetLog['reward']['spins'] * ( $TurnPaybetLog['bet'] - 1 );
                oo::commonOprModel('member')->optProperty($uid,['spins'=>$gbaseReward],'+',500,'支付加倍获得体力:'.$orderId.",bet:".$TurnPaybetLog['bet']);
                $data['data']=['spins'=>$gbaseReward];
                if(isset($TurnPaybetLog['reward']['gtype'])&&$TurnPaybetLog['reward']['gtype']==1){//充值体力时,判断是否有体力大师活动加进度
//                    oo::commonOprModel('activitynew')->addCommonScore($uid,'spins_master',intval($gbaseReward));
                }
                return ($returnJson?oo::response(1):true);
            }else{
                oo::logs()->debug5(['uid'=>$uid,'支付加倍'=>'奖励没有体力','time'=>time()],date('Ymd').'.log','payBet/');
            }
        }else{
            oo::logs()->debug5(['uid'=>$uid,'支付加倍'=>'redis key 丢失','time'=>time()],date('Ymd').'.log','payBet/');
        }
        return ($returnJson?oo::response(-2,[],'支付加倍转盘 发货失败'):false);
    }

    /**
     * 新版发货
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2020/4/26 16:59
     */
    public function payment2($param){
        $uid = oo::functions()->uint($param['uid']);
        $sid = !empty($param['sid']) ? (int)$param['sid'] : oo::getDefinedSid($uid);
        $deviceid = oo::getDefinedDeviceId($uid, $sid);
        switch ($deviceid){
            case 2:
                $extraData  = json_decode(base64_decode(oo::functions()->escape($param['extraData'])),true);
                if(empty($extraData)){
                    $iosInApp = oo::commonOprModel('paymentapple')->validateApplePay($param);
                    $sku      = str_replace('newsky.cc','sa.crazygod',$iosInApp['product_id']);
                    $tb  = otable::goodsCrazy();
                    $goodInfo = oo::commonOprDb('payment')->getOne("SELECT * FROM {$tb} WHERE gsku='{$sku}' LIMIT 1",MYSQLI_ASSOC);
                    $extraData = [
                        'uid'      => $uid,
                        'gid'      => $goodInfo['gid'],
                        'ggameid'  => $goodInfo['ggameid'],
                    ];
                }
                $orderStatus= self::createOrder($extraData);
                if($orderStatus['code'] == 1){
                    $param['orderId'] = $orderStatus['orderId'];
                    $param['version'] = $orderStatus['version'];
                    return self::payment($param,true);
                }
            break;
            default:
                $signedData = base64_decode($param['signedData']);
                $signedData = json_decode($signedData, true);
                if( !is_array($signedData) ){
                    return json_encode(['code'=>-4,'msg'=>'signedData error']);
                }
                if($param['signature'] != 'fakesignature'){
                    $ret = oo::commonOprModel('paymentgoogle')->validateGooglePay($param);//验证失败
                    if(!$ret){
                        return json_encode(['code'=>-3,'msg'=>'Google sign error']);
                    }
                    $googleOrderId = $signedData['orderId'];
                    $purchaseTime  = intval($signedData['purchaseTime']/1000);
                    $tb = otable::summarylist();
                    $sql= "SELECT * FROM {$tb} WHERE sl_platform_serial_num='{$googleOrderId}' AND sl_pay_time>={$purchaseTime} LIMIT 1";
                    $ret= oo::commonOprDb('common')->getOne($sql,MYSQLI_ASSOC);
                    if(!empty($ret)){
                        return json_encode(['code'=>1,'google orderId was used']);
                    }
                }
                $orderInfo  = json_decode(base64_decode($signedData['developerPayload']),true);
                $orderStatus= self::createOrder($orderInfo);
                if($orderStatus['code'] == 1){
                    $param['orderId'] = $orderStatus['orderId'];
                    $param['version'] = $orderStatus['version'];
                    return self::payment($param,true);
                }
        }
        return oo::response(-2,[],'订单创建失败');
    }

    //三方支付订单验证
    private function checkPlatOrder(array $param) {
        if(empty($param['plat']) || empty($param['orderId'])){
            return false;
        }
        $uid = oo::functions()->uint($param['uid']);
        $orderId = $param['orderId'];
        switch($param['plat']){
            case 'vivo':
                $region = empty($param['region']) ? '' : $param['region'];
                if(!oo::commonOprModel('paymentvivo')->qryOrder($orderId, $uid, $region)){
                    oo::logs()->debug3(array('uid' => $uid, 'data' => $param), 'vivoOrder.log');
                    return false;
                }
                return true;
            default:
        }
        return false;
    }

    /**
     * 谷歌、vivo、测试等类型签名验证
     * @param array $signedData
     * @param int array $orderInfo
     * @return mixed
     */
    public function verifySignature(array $signedData = [], array $orderInfo = [], $param = []) {
        $orderId = $orderInfo['orderId'];
        if(!funs::concurrentLock($orderId,'PlatformSerialNum',6)){
            return ['code'=>-500,'msg'=>'order be locked','err'=>9];
        }

        if($param['signature'] == 'fakesignature'){
            return true;
        }

        //vivo pay
        if(!empty($param['plat'])){
            if(IS_DEBUF){
                return true;
            }else{
                return $this->checkPlatOrder($param);
            }
        }

        //google pay
        $purchaseTime  = intval($signedData['purchaseTime']/1000);
        $googleOrderId = $signedData['orderId'];
        $tb = otable::summarylist();
        $sql= "SELECT * FROM {$tb} WHERE sl_platform_serial_num='{$googleOrderId}' AND sl_pay_time>={$purchaseTime} LIMIT 1";
        $ret= oo::commonOprDb('common')->getOne($sql,MYSQLI_ASSOC);
        if(!empty($ret)){
            return ['code'=>1,'google orderId was used','err'=>10];
        }
        if(!oo::commonOprModel('paymentgoogle')->validateGooglePayOauth($signedData,$param)){//验证失败
            return ['code'=>-3,'msg'=>'Google sign error','err'=>11];
        }
        return true;
    }

    /**
     * 支付auth 2.0
     * @param $param
     * @return false|string
     * Created by: Owen
     * Created on: 2020/8/6 16:27
     */
    public function payment3($param){
        $uid = oo::functions()->uint($param['uid']);
        $sid = !empty($param['sid']) ? (int)$param['sid'] : oo::getDefinedSid($uid);
        $deviceid = oo::getDefinedDeviceId($uid, $sid);
        $tss['ts1'] = oo::getMsectime();
        switch ($deviceid){
            case 2:
                $extraData  = json_decode(base64_decode(oo::functions()->escape($param['extraData'])),true);
                $serialNo  = isset($param['transactionId']) ? $param['transactionId'] : '0';
                if(empty($extraData)){
                    $iosInApp = oo::commonOprModel('paymentapple')->validateApplePay($param);
                    $sku      = str_replace('astak.crazyspin','gworld.cc',$iosInApp['product_id']);
                    $tb  = otable::goodsCrazy();
                    $goodInfo = oo::commonOprDb('payment')->getOne("SELECT * FROM {$tb} WHERE gsku='{$sku}' LIMIT 1",MYSQLI_ASSOC);
                    $extraData = [
                        'uid'      => $uid,
                        'gid'      => $goodInfo['gid'],
                        'ggameid'  => $goodInfo['ggameid'],
                    ];
                }
                if(empty($param['gid']) && !empty($extraData['gid'])){
                    $param['gid'] = $extraData['gid'];
                }
                $oldOrder = [];
                if((string)$serialNo && $serialNo !== '0'){
                    $extraData['serialNo'] = $serialNo;
                    $tb       = otable::payment($uid);
                    $sql      = "SELECT * FROM {$tb} WHERE uid={$uid} AND platform_serial_num='{$serialNo}' LIMIT 1";
                    $oldOrder = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
                }
                if(!empty($oldOrder)){
                    $gid 		 = oo::functions()->uint($param['gid']);
                    $orderStatus = ['code' => 1, 'orderId' => $oldOrder['order_id'], 'gid' => $gid];
                }else{
                    $orderStatus = self::createOrder($extraData);
                }
                $tss['ts5'] = oo::getMsectime();
                if($orderStatus['code'] == 1){
                    $param['orderId'] = $orderStatus['orderId'];
                    $param['version'] = $orderStatus['version'];
                    $ret = self::payment($param,true);
                    //日志记录
                    $tss['ts6'] = oo::getMsectime();
                    $passTs = $tss['ts6']-$tss['ts1'];
                    if($passTs>2000){
                        oo::logs()->debug3(['ts'=>$tss,'gid'=>$extraData['gid'],"uid"=>$param['uid']],'paymentTime.log');
                    }
                    $retArr = json_decode($ret,true);
                    if($retArr['err']&&!in_array(intval($extraData['gid']),[801,803])){
                        oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$retArr],'payment_err.log');
                    }
                    return $ret;
                }
                break;
            default:
                $signedData = base64_decode($param['signedData']);
                $signedData = json_decode($signedData, true);
                if( !is_array($signedData) ){
                    $ret = json_encode(['code'=>-4,'msg'=>'signedData error','err'=>12]);
                    oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$ret],'payment_err.log');
                    return $ret;
                }
                $orderInfo=empty($param['extraData'])?[]:(array)json_decode(base64_decode($param['extraData']),true);
                $uid = oo::functions()->uint($param['uid']);
                if(empty($uid)){
                    $ret = json_encode(['code'=>-500,'msg'=>'order info error','err'=>13]);
                    oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$ret],'payment_err.log');
                    return $ret;
                }
                //预处理订单号
                if(!empty($param['plat'])){
                    if(empty($param['orderId']) || strlen($param['orderId']) != 32){
                        //vivo或其他支付平台需传递orderid
                        $ret = json_encode(['code'=>-500,'msg'=>'3rd plat order id error','err'=>14]);
                        oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$ret],'payment_err.log');
                        return $ret;
                    }
                    $orderInfo['orderId'] = $param['orderId'];
                    $orderInfo['plat'] = $param['plat'];
                }else{
                    $orderInfo['orderId'] = $this->createOrderId($uid, self::GGAMEID);
                }
                $orderInfo['uid'] = $uid;
                if(empty($orderInfo['gid']) && !empty($orderInfo['serialNo'])){
                    $matchNum = preg_match('/^GPA.*\.\.\d$/', $orderInfo['serialNo'], $matchRes);
                    $matchNum && $orderInfo['gid'] = 801; //gid为0的订单,尾部带了2个点的自动转化为801订阅商品
                }
                $ret = $this->verifySignature($signedData, $orderInfo, $param);
                if(is_array($ret) || !$ret){
                    if(!(in_array(intval($orderInfo['gid']),[801,803])&&isset($ret['err'])&&intval($ret['err'])==10)){
                        oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$ret],'payment_err.log');
                    }
                    return json_encode((array)$ret);
                }

                $orderStatus= self::createOrder($orderInfo);
                $tss['ts5'] = oo::getMsectime();
                if($orderStatus['code'] == 1){
                    $param['orderId'] = $orderStatus['orderId'];
                    $param['version'] = $orderStatus['version'];
                    $ret = self::payment($param,true);
                    //日志记录
                    $tss['ts6'] = oo::getMsectime();
                    $passTs = $tss['ts6']-$tss['ts1'];
                    if($passTs>2000){
                        oo::logs()->debug3(['ts'=>$tss,'gid'=>$orderInfo['gid'],"uid"=>$orderInfo['uid']],'paymentTime.log');
                    }
                    $retArr = json_decode($ret,true);
                    if($retArr['err']&&!in_array(intval($orderInfo['gid']),[801,803])){
                        oo::logs()->debug3(["ts"=>time(),"uid"=>$param['uid'],"param"=>$param,"err"=>$ret],'payment_err.log');
                    }
                    return $ret;
                }
        }
        return oo::response(-2,[],'订单创建失败');
    }


    /**
     * 获取体力月卡的状态
     * @param $uid
     * @param $gid
     * @return mixed
     * Created by: Owen
     * Created on: 2019/12/25 15:00
     */
    public function getSpinMonthly($uid,$gid){
        $status = oo::commonOprRedis('usercache')->get(okeys::SpinMonthly($uid,$gid));
        if($status === 0){
            return false;
        }
        if($status === false){
            $tb   = otable::payment($uid);
            $time = time();
            $sql  = "SELECT * FROM {$tb} WHERE status=2 AND uid={$uid} AND gid={$gid} AND buff>'{$time}' ORDER BY buff DESC LIMIT 1";
            $ret  = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
            if(!empty($ret)){
                $tb = otable::goodsCrazy();
                $sql   = "SELECT * FROM {$tb} WHERE gid={$gid}";
                $goods = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
                $reward = json_decode($goods['gbaseReward'],true);
                $record  = [
                    'endTime'=>$ret['buff'],
                    'num'    =>$reward['daily'],
                ];
                $endTime  = strtotime("23:59:59") + 29*24*60*60;
                if($ret['buff'] > $endTime){
                    $expire = $endTime - time();
                }else{
                    $expire = $ret['buff'] - time();
                }
                oo::commonOprRedis('usercache')->setex(okeys::SpinMonthly($uid,$gid),json_encode($record,JSON_NUMERIC_CHECK),$expire);
                return $record;
            }else{
                oo::commonOprRedis('usercache')->setex(okeys::SpinMonthly($uid,$gid),0,7*24*60*60);
            }
        }else{
            return  json_decode($status,true);
        }
    }

    /**
     * 获得用户充值总值
     * @param $uid
     * @param $day
     * @return mixed
     * Created by: owen
     * Created on: 2020/2/6 16:56
     */
    public function getUserTotalPayNum($uid,$day = 0){
        $cacheKey = okeys::UserTotalPayNum($uid);
        $cache = oo::commonOprRedis('User')->hGet($cacheKey,$day);
        if($cache !== false){
            return $cache;
        }
        $tb = otable::payment($uid);
        if($day > 0){
            $time= time() - $day * 24*60*60;
            $sql = "SELECT COALESCE(SUM(pusd),0) AS sum FROM {$tb} WHERE uid={$uid} AND status=2 AND pay_time>{$time}";
        }else{
            $sql = "SELECT COALESCE(SUM(pusd),0) AS sum FROM {$tb} WHERE uid={$uid} AND status=2";
        }
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        $sum = round($ret['sum'],2);
        oo::commonOprRedis('User')->hSet($cacheKey,$day,$sum);
        oo::commonOprRedis('User')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
        return $sum;
    }

    /**
     * 获得用户充值总次数
     * @param $uid
     * @return false|int
     * Created by: Owen
     * Created on: 2020/12/1 15:06
     */
    public function getUserPayTimes($uid,$day = 0){
        $cacheKey = okeys::UserPayTimes($uid);
        $cache = oo::commonOprRedis('User')->hGet($cacheKey,$day);
        if($cache !== false){
            return intval($cache);
        }
        $tb = otable::payment($uid);
        if($day){
            $time= time() - $day * 24*60*60;
            $ret = oo::commonOprDb('payment')->getOne("SELECT COUNT(*) AS count FROM {$tb} WHERE uid={$uid} AND status=2 AND pay_time>{$time}",MYSQLI_ASSOC);
        }else{
            $ret = oo::commonOprDb('payment')->getOne("SELECT COUNT(*) AS count FROM {$tb} WHERE uid={$uid} AND status=2",MYSQLI_ASSOC);
        }
        oo::commonOprRedis('User')->hSet($cacheKey,$day,intval($ret['count']));
        oo::commonOprRedis('User')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
        return intval($ret['count']);
    }

    /**
     * Notes:获取首次支付时间
     * User: wsc
     * Time: 2021/6/8 10:19
     * @param $uid
     * @param bool $db
     * @return false|string
     */
    public function getUserFirstPayTS($uid,$db=false){
        $key = okeys::UserFirstPayTS($uid);
        $cache = oo::commonOprRedis('User')->get($key);
        if(!$cache||$db){
            oo::commonOprRedis('User')->delete($key);
            $tb = otable::payment($uid);
            $sql = "SELECT pay_time FROM {$tb} WHERE uid={$uid} and status=2 ORDER BY pay_time ASC LIMIT 1";
            $info = oo::commonOprDb('payment')->getOne($sql,1);
            if($info){
                $cache = $info['pay_time'];
            }else{
                $cache = 1;
            }
            oo::commonOprRedis('User')->setex($key,$cache,7*86400);
        }
//        else{
//            oo::commonOprRedis('User')->expire($key,7*86400);
//        }
        if($cache>1){
            $ts = $cache;
        }else{
            $ts = 0;
        }
        return $ts;
    }

    /**
     * 当天充值金额
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/4/23 11:36
     */
    public function getUserDayPayNum($uid){
        $cache = oo::commonOprRedis('User')->get(okeys::UserDayPayNum($uid));
        if(!empty($cache)){
            return $cache;
        }
        $tb = otable::payment($uid);
        $startTime = strtotime("00:00:00");
        $endTime = strtotime("23:59:59");
        $sql = "SELECT COALESCE(SUM(pusd),0) AS sum FROM {$tb} WHERE uid={$uid} AND status=2 AND pay_time>{$startTime} AND pay_time<{$endTime}";
        $ret = oo::commonOprDb('payment')->getOne($sql,MYSQLI_ASSOC);
        $sum = round($ret['sum'],2);
        oo::commonOprRedis('User')->setex(okeys::UserDayPayNum($uid),$sum,24*60*60);
        return $sum;
    }

    /**
     * 购买矿工小游戏次数
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/5/12 12:20
     */
    public function buyMiningGameCount($uid){
        $coins =  oo::commonOprModel('goods')->getGoodCoins($uid,'coins01');
        $coins = intval($coins * 0.25);
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        if($userInfo['money'] < $coins){
            return oo::response(-2,[],'金币不足');
        }
        $ret = oo::commonOprModel('member')->optProperty($uid,array('money'=>$coins),'-',22,"矿工小游戏");
        if($ret){
            $ttl   = max(0,oo::commonOprRedis('common')->ttl(okeys::MiningGame($uid)));
            $count = intval(oo::commonOprRedis('common')->get(okeys::MiningGame($uid)));
            oo::commonOprRedis('common')->setex(okeys::MiningGame($uid),max(0,$count-1),$ttl);
            oo::commonOprRedis('common')->hIncrBy(okeys::MiningGame(),$uid,-1);
            return oo::response(1,oo::commonOprModel('mining')->getGameInfo($uid,2),'',true);
        }
        return oo::response(-2,[],'金币不足');
    }

    /**
     * 购买矿工小游戏次数
     * @param $uid
     * @return string
     * Created by: Owen
     * Created on: 2020/5/12 12:20
     */
    public function buyMiningGameCountByDiamond($uid){
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $refreshTimeDiamondNum = oo::commonOprModel('mining')->getRefreshTimeDiamond();
        if($userInfo['diamond'] < $refreshTimeDiamondNum){
            return oo::response(errorCode::DIAMOND_NOT_ENOUGH,[],'钻石不足');
        }
        $ret = oo::commonOprModel('member')->optProperty($uid,array('diamond'=>$refreshTimeDiamondNum),'-',22,"矿工小游戏");
        if($ret){
            $ttl   = max(0,oo::commonOprRedis('common')->ttl(okeys::MiningGame($uid)));
            $count = intval(oo::commonOprRedis('common')->get(okeys::MiningGame($uid)));
            oo::commonOprRedis('common')->setex(okeys::MiningGame($uid),max(0,$count-1),$ttl);
            oo::commonOprRedis('common')->hIncrBy(okeys::MiningGame(),$uid,-1);
            return oo::response(1,oo::commonOprModel('mining')->getGameInfo($uid,2),'',true);
        }
        return oo::response(errorCode::DIAMOND_NOT_ENOUGH,[],'钻石不足');
    }


    /**
     * ios vip 监听定时器
     * Created by: Owen
     * Created on: 2020/5/12 20:36
     */
    public function vipMonitor(){
        $_urlBuy = "https://buy.itunes.apple.com/verifyReceipt";
        $_urlSanbox = "https://sandbox.itunes.apple.com/verifyReceipt";
        $tb  = otable::subscription(2);
        $summarylist = otable::summarylist();
        $ret = oo::commonOprRedis('common')->zRangeByScore(okeys::VipMonitor(),0,time() - 24*60*60,['withscores'=>true]);
        foreach ($ret as $transaction_id => $time){
            $ret = oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE transaction_id='{$transaction_id}' LIMIT 1",1);
            if(!empty($ret)){
                $receipt = $ret['latest_receipt'];
                $postDataArr = array("receipt-data" => $receipt , "password" => "b8dd1ad711de4bbdb7b08a4fa2706b04");
                $postData = json_encode($postDataArr);
                $iosData = oo::functions()->curl($_urlBuy, $postData);
                if($iosData['status'] === 0){
                    $expires_date = ceil($iosData['latest_receipt_info']['expires_date']/1000);
                    if(time() < $expires_date){
                        $transaction_uid = oo::commonOprDb('common')->getOne("SELECT * FROM {$summarylist} WHERE sl_platform_serial_num='{$transaction_id}' LIMIT 1",MYSQLI_ASSOC);
                        oo::commonOprModel('member')->getUserInfo($transaction_uid['sl_uid'], NULL, TRUE,[
                            'svip'        => 1,
                            'svip_expire' => $expires_date,
                        ]);
                        oo::commonOprRedis('common')->zAdd(okeys::VipMonitor(),$expires_date,$transaction_id);
                    }else{
                        oo::commonOprRedis('common')->zDelete(okeys::VipMonitor(),$transaction_id);
                    }
                }elseif($iosData['status'] == 21007){//沙盒测试
                    $iosData = oo::functions()->curl($_urlSanbox, $postData);
                    if($iosData['status'] === 0){
                        $expires_date = ceil($iosData['latest_receipt_info']['expires_date']/1000);
                        if(time() < $expires_date){
                            $transaction_uid = oo::commonOprDb('common')->getOne("SELECT * FROM {$summarylist} WHERE sl_platform_serial_num='{$transaction_id}' LIMIT 1",MYSQLI_ASSOC);
                            oo::commonOprModel('member')->getUserInfo($transaction_uid['sl_uid'], NULL, TRUE,[
                                'svip'        => 1,
                                'svip_expire' => $expires_date,
                            ]);
                            oo::commonOprRedis('common')->zAdd(okeys::VipMonitor(),$expires_date,$transaction_id);
                        }else{
                            oo::commonOprRedis('common')->zDelete(okeys::VipMonitor(),$transaction_id);
                        }
                    }
                }
            }
        }
    }

    /**
     * 购买星星兑换次数
     * @param $uid
     * @param $propsId
     * @return string
     * Created by: Owen
     * Created on: 2020/6/10 20:46
     */
    public function starExchange($uid,$propsId){
        $config   = oo::commonOprModel('config')->getStarExchange($propsId);
        $cacheKey = okeys::StarExchangeBuyTimer($uid,$propsId);
        $timer    = intval(oo::commonOprRedis('User')->get($cacheKey));
        if($timer >= count($config['chestPrice'])){
            return oo::response(-2,"","达到购买上限");
        }
        $bet = $config['chestPrice'][$timer];
        if(empty($bet)){
            return oo::response(-2,"","达到购买上限");
        }
        $refreshTime = intval(oo::commonOprRedis('User')->ttl(okeys::StarExchange($uid,$propsId)));
        if($refreshTime <= 0){
            return oo::response(-2,"","购买异常");
        }
        $userInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $coins    = oo::commonOprModel('config')->getActivityCoins(max($userInfo['levelId'],1),"starExchange");
        $coins = $coins * $bet;
        if($userInfo['money'] < $coins){
            return oo::response(-2,"","金币不足");
        }
        $ret   = oo::commonOprModel('member')->optProperty($uid,['money'=>$coins],'-',33,"购买星星兑换次数");
        if($ret > 0){
            oo::commonOprRedis('User')->setex($cacheKey,$timer+1,$refreshTime);
            oo::commonOprRedis('User')->delete(okeys::StarExchange($uid,$propsId));
            return oo::response(1);
        }else{
            return oo::response(-2,"","金币不足");
        }
    }

    /**
     * 连环礼包
     * @param $uid
     * @param $gid
     * @return string
     * Created by: Owen
     * Created on: 2020/6/12 14:29
     */
    public function buyGift($uid,$gid){
        if(in_array($gid,[710,711,712])){
            $cacheKey = okeys::SerialPackTimer($uid,$gid);
            $timer    = oo::commonOprRedis('common')->hGet(okeys::SerialPackTimer(),$cacheKey);
            $goodInfo = oo::commonOprModel('goods')->getGoodsInfoByGid($gid);
            if($timer >= $goodInfo['gMax']){
                return oo::response(-2,[],"次数达到上限");
            }
            if(strpos($goodInfo['gsku'],'com.sa') !== false||strpos($goodInfo['gsku'],'com.gworld') !== false||strpos($goodInfo['gsku'],'gworld.cc') !== false||strpos($goodInfo['gsku'],'astak.crazyspin') !== false){
                return oo::response(-2,[],"商品异常");
            }
            $price  = json_decode($goodInfo['gsku'],true);
            $price  = oo::commonOprModel('goods')->getGoodCoins($uid,$price['coins']) * $price['bet'];
            $money = oo::commonOprModel('member')->getUserAssetsInfo($uid)['money'];
            if(intval($price)>0&&$money<intval($price)){
                return oo::response(-2,[],"金币不足");
            }
            oo::commonOprModel('member')->optProperty($uid,['money'=>$price],'-',450,$goodInfo['gdesc']);
            $reward = json_decode($goodInfo['gbaseReward'],true);
            $coin   = oo::commonOprModel('goods')->getGoodCoins($uid,$reward['coins']['coins']) * $reward['coins']['bet'];
            oo::commonOprModel('member')->optProperty($uid,['money'=>$coin,'spins'=>$reward['spins']],'+',450,$goodInfo['gdesc']);
            $data   = [];
            foreach ($reward['props'] as $row){
                if(in_array($row['propsId'],[19,20,21,29,30])){
                    $skin = isset($row['skin']) ? (int)$row['skin'] : 0;
                    $data['treasureChest'] = oo::commonOprModel('props')->rewardChest($uid,$row['propsId'],'',450, $skin);
                }else{
                    oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],450,$goodInfo['gdesc']);
                }
            }
            oo::commonOprRedis('common')->hIncrBy(okeys::SerialPackTimer(),$cacheKey,1);
            return oo::response(1,$data,"",true);
        }
        return oo::response(-2,[],"商品异常");
    }

    /**
     * Notes:连环礼包领奖
     * User: wsc
     * Time: 2020/8/21 17:17
     * @param $uid
     * @param $aid
     * @param $gid
     * @return string
     */
    public function buyGiftNew($uid,$aid,$gid){
        if(in_array($gid,[710,711,712])){
            $res  =$this->sendGift($uid,$aid,$gid,1);
            if($res==-1){
                return oo::response(-2,[],"次数达到上限");
            }
            if($res==-2){
                return oo::response(-2,[],"金币不足");
            }
            if($res==-3){
                return oo::response(-2,[],"该商品需付费");
            }
            return oo::response(1,$res);
        }
        return oo::response(-2,[],"商品异常");
    }

    /**
     * Notes:连环礼包奖励发放
     * User: wsc
     * Time: 2020/8/21 18:02
     * @param $uid
     * @param $aid
     * @param $gid
     * @return array
     */
    public function sendGift($uid,$aid,$gid,$d=0){
        $cacheKey = $uid.'_'.$gid;
        $timer    = oo::commonOprRedis('activity')->hGet(okeys::buyChainGiftLimit($aid),$cacheKey);
        $goodInfo = oo::commonOprModel('activitynew')->getChainGiftConf($uid,$aid,$gid);
        if($timer >= $goodInfo['gMax']){
            return -1;
        }

        if($d==1&&$goodInfo['sku']){
            return -3;
        }
        if(intval($goodInfo['price'])>0&&!$goodInfo['sku']){
            $money = oo::commonOprModel('member')->getUserAssetsInfo($uid)['money'];
            if($money<intval($goodInfo['price'])){
                return -2;
            }
            oo::commonOprModel('member')->optProperty($uid,['money'=>$goodInfo['price']],'-',450,$goodInfo['gdesc']."--gid:{$gid}--aid:{$aid}");
        }
        $reward['reward'] = $goodInfo['gbaseReward'];
        oo::commonOprModel('member')->optProperty($uid,['money'=>$goodInfo['coin'],'spins'=>$goodInfo['spin']],'+',450,$goodInfo['gdesc']."--gid:{$gid}--aid:{$aid}");
        foreach ($goodInfo['props'] as $k=>$row){
            if(in_array($row['propsId'],[19,20,21,29,30])){
                $skin = isset($row['skin']) ? (int)$row['skin'] : 0;
                $reward['treasureChest'] = oo::commonOprModel('props')->rewardChest($uid,$row['propsId'],'',450, $skin);
                $goodInfo['props'][$k]['value'] = $reward['treasureChest'];
            }else{
                $res = oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],450,$goodInfo['gdesc']."--gid:{$gid}--aid:{$aid}",$aid);
                if(in_array($row['propsId'],[13,18,19,20,21,29,30])){
                    $goodInfo['props'][$k]['value'] =$res;
                }
            }
        }
        oo::commonOprRedis('activity')->hIncrBy(okeys::buyChainGiftLimit($aid),$cacheKey,1);
        $reward['props'] = $goodInfo['props'];
        return $reward;
    }

    /**
     * Notes:购买超级连环礼包
     * User: wsc
     * Time: 2020/11/25 19:54
     * @param $uid
     * @param $aid
     * @param $gid
     * @return string
     */
    public function buySuperSerialPack($uid,$aid,$gid){
        if(!$aid){
            return oo::response(errorCode::NOT_FOUND_ACTIVITY,[],"活动未绑定");
        }
        if(($gid>720&&$gid<=750)||($gid>760&&$gid<=790)){
            $res  =$this->sendReward($uid,$gid,$aid,1);
            if($res==-1){
                return oo::response(errorCode::NOT_FOUND_GOODINFO,[],"商品信息不存在");
            }
            if($res==-2){
                return oo::response(errorCode::LIMIT_NOT_RNOUGH,[],"次数达到上限");
            }
            if($res==-3){
                return oo::response(errorCode::MONEY_NOT_RNOUGH,[],"金币不足");
            }
            if($res==-4){
                return oo::response(errorCode::CONDITION_NOT_RNOUGH,[],"该商品需付费");
            }
            return oo::response(1,$res);
        }
        return oo::response(-2,[],"商品异常");
    }
    /**
     * Notes:发奖
     * User: wsc
     * Time: 2020/11/25 15:51
     * @param $uid
     * @param $gid
     * @param int $aid
     * @param int $d 0内部发货,1外部购买
     * @return array
     */
    public function sendReward($uid,$gid,$aid=0,$d=0){
        $reward =[];
        if((($gid>720&&$gid<=750)||($gid>760&&$gid<=790))&&$aid){//超级连环礼包\
            $tip = $gid>720&&$gid<=750?"超级连环":"超级连环2";
            $cacheKey = $uid.'_'.$gid;
            $timer = oo::commonOprModel('activitynew')->getBuySuperSerialPackLimit($aid,$uid,$gid);
//            $timer    = oo::commonOprRedis('activity')->hGet(okeys::buySuperSerialPackLimit($aid),$cacheKey);
            $goodInfo = oo::commonOprModel('activitynew')->getCGRewardByGid($uid,$aid,$gid);
            if(empty($goodInfo)){
                return -1;
            }
            if($timer >= $goodInfo['gMax']){
                return -2;
            }
            if($d==1&&$goodInfo['sku']){//外部购买
                return -4;
            }
            if($goodInfo['mtype']==1){//金币购买
                $money = oo::commonOprModel('member')->getUserAssetsInfo($uid)['money'];
                if($money<intval($goodInfo['price'])){
                    return -3;
                }
                oo::commonOprModel('member')->optProperty($uid,['money'=>$goodInfo['price']],'-',451,$goodInfo['name']."{$tip}--gid:{$gid}--aid:{$aid}");
            }
            $reward['sku'] = $goodInfo['sku'];
            foreach ($goodInfo['props'] as $k=>$row){
                $ret = oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],451,$goodInfo['name']."{$tip}--gid:{$gid}--aid:{$aid}",$row['value'],$row);
                if(in_array($row['propsId'],[19,20,21,29,30])){
                    $reward['treasureChest'] = $ret;
                }
                if(in_array($row['propsId'],[13,18,19,20,21,29,30])){
                    $goodInfo['props'][$k]['value'] = $ret;
                }
            }
            $reward['props'] = $goodInfo['props'];
            oo::commonOprModel('activitynew')->addBuySuperSerialPackLimit($aid,$uid,$gid);
//            oo::commonOprRedis('activity')->hIncrBy(okeys::buySuperSerialPackLimit($aid),$cacheKey,1);
        }
        else if($gid>750&&$gid<=760){
            $goodInfo = oo::commonOprModel('activitynew')->getEasterGiftBag($uid,$gid);
            $reward['sku'] = $goodInfo['sku'];
            foreach ($goodInfo['props'] as $row){
                $ret = oo::commonOprModel('member')->sendReward($uid,$row['propsId'],$row['num'],453,$goodInfo['name']."复活礼包--gid:{$gid}--aid:{$aid}",$row['value'],$row);
            }
            $reward['props'] = $goodInfo['props'];
        }
        return $reward;
    }

    /**
     * 购买礼包的次数
     * @param $uid
     * @param $day
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/28 14:43
     */
    public function getBuyGiftNum($uid,$day){
        $cacheKey = okeys::UserBuyGiftNum($uid);
        $cache    = oo::commonOprRedis('User')->hGet($cacheKey,$day);
        if($cache){
            return $cache;
        }
        $day2= time() - $day * 24*60*60;
        $tb = otable::payment($uid);
        $sql= "SELECT COUNT(*) as count FROM {$tb} WHERE uid={$uid} AND status=2 AND pay_time>{$day2} AND ((gid>700 AND gid<800) OR (gid>1600 AND gid<1700))";
        $ret= oo::commonOprDb('common')->getOne($sql,MYSQLI_ASSOC);
        oo::commonOprRedis('User')->delete($cacheKey);
        oo::commonOprRedis('User')->hSet($cacheKey,$day,$ret['count']);
        oo::commonOprRedis('User')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
        return $ret['count'];
    }

    /**
     * 更新支付统计数据缓存
     * @param $uid
     * @param $gid
     * @param $num
     * Created by: Owen
     * Created on: 2020/6/28 15:32
     */
    public function updateUserPayCache($uid,$gid,$num){
        if(($gid>700 && $gid<800) || ($gid>1600 && $gid<1700)){
            $cacheKey = okeys::UserBuyGiftNum($uid);
            $cache    = oo::commonOprRedis('User')->hGetAll($cacheKey);
            foreach ($cache as $key=>$row){
                oo::commonOprRedis('User')->hIncrBy($cacheKey,$key,1);
            }
        }

        $cacheKey = okeys::UserTotalPayNum($uid);
        $cache    = oo::commonOprRedis('User')->hGetAll($cacheKey);
        foreach ($cache as $key=>$row){
            oo::commonOprRedis('User')->hIncrBy($cacheKey,$key,$num);
        }
        oo::commonOprRedis('User')->expire($cacheKey,oo::redisRandomExpire(7*24*60*60));
        oo::commonOprRedis('User')->incrBy(okeys::UserDayPayNum($uid),$num);
        oo::commonOprRedis('User')->expire(okeys::UserDayPayNum($uid),oo::redisRandomExpire(3*24*60*60));
        oo::commonOprRedis('User')->setex(okeys::UserLastPayTime($uid),time(),oo::redisRandomExpire(3*24*60*60));
        oo::commonOprRedis('User')->delete([okeys::UserPayTimes($uid),okeys::CMSUserPayData($uid)]);
    }

    /**
     * 用戶最後購買時間
     * @param $uid
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/30 14:40
     */
    public function getUserLastPayTime($uid){
        $cacheKey = okeys::UserLastPayTime($uid);
        $cache    = oo::commonOprRedis('User')->get($cacheKey);
        if($cache !== false){
            return intval($cache);
        }
        $tb = otable::payment($uid);
        $sql= "SELECT * FROM {$tb} WHERE uid={$uid} AND status=2 ORDER BY pid DESC LIMIT 1";
        $ret= oo::commonOprDb('common')->getOne($sql,MYSQLI_ASSOC);
        $lastTime = max(intval($ret['pay_time']),0);
        oo::commonOprRedis('User')->setex($cacheKey,$lastTime,7*24*60*60);
        return $lastTime;
    }

    /**
     * 支付转盘加倍
     * @param $uid
     * @param $gid
     * @param $gprice
     * @param $data
     * @return mixed
     * Created by: Owen
     * Created on: 2020/7/21 18:02
     */
    public function payTurnTabBet($uid,$gid,$gprice,$data){
        //支付转盘加倍
        //获取转盘出现配置
        $config = oo::commonOprModel('config')->getTurnPaybetConfig('price');
        $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
        $showPriceArr = $vipPointRet = $maxNum = [];
        $vipPoint = $userInfo['vipPoint'];//用户积分
        foreach ($config as $k => $v){
            if($v['price'] === '0' || $v['price'] == '-1' || $v['price'] >= $gprice){
                foreach($v['list'] as $listRow){
                    if($listRow['mixPoint'] <= $vipPoint){
                        $showPriceArr[$v['price']] = $listRow['probability'];
                        $vipPointRet[$v['price']] = $listRow['mixPoint'];
                        $maxNum[$v['price']] = $listRow['maxNum'];
                    }
                }
            }
        }
        $temp  = oo::commonOprModel('slot')->get_rand($showPriceArr);
        if($temp != '-1'){
            if(intval(oo::commonOprRedis('common')->hGet(okeys::TurnPaybetNum($temp,$vipPointRet[$temp]),$uid)) >= $maxNum[$temp]){
                //该积分+价格 出现次数已超过等于最大次数
                return $data;
            }
            $configBet = oo::commonOprModel('config')->getTurnPaybetConfig('bet');
            $betRet = [];
            foreach($configBet as $k => $v){
                if($v['price'] == $temp){
                    $rate = [];
                    $list = [];
                    foreach($v['list'] as $listKey => $listVal){
                        $rate[] = $listVal[1];
                        $list[] = $listVal[0];
                    }
                    $betRet[$v['price']]['rate'] = $rate;
                    $betRet[$v['price']]['list'] = $list;
                }
            }
            if(!empty($betRet[$temp])){
                $betId = oo::commonOprModel('slot')->get_rand($betRet[$temp]['rate']);
                $data['data']['multiPay']['reward'] = $data['data'];
                $data['data']['multiPay']['bet'] = intval($betRet[$temp]['list'][$betId]);
                $data['data']['multiPay']['gid'] = 0;
                $data['data']['multiPay']['betGid'] = intval($gid);
                $data['data']['multiPay']['gprice'] = $temp;
                foreach($betRet[$temp]['list'] as $key => $betTemp){
                    $betRet[$temp]['list'][$key] = intval($betTemp);
                }
                $data['data']['multiPay']['betConfig'] = $betRet[$temp]['list'];

                if($temp != 0){
                    $tb  = otable::goodsCrazy();
                    $sql = "SELECT * FROM {$tb} WHERE gprice={$temp} AND gtype = 17";
                    $payBetGoodInfo = oo::commonOprDb('payment')->getOne($sql,1);
                    $data['data']['multiPay']['gid'] = intval($payBetGoodInfo['gid']);
                }

                oo::commonOprRedis('common')->hSet(okeys::TurnPaybetLog(),$uid,json_encode($data['data']['multiPay']));//记录获得的bet
                oo::commonOprRedis('common')->hIncrBy(okeys::TurnPaybetNum($temp,$vipPointRet[$temp]),$uid,1);//添加次数
            }
        }
        return $data;
    }

    /**
     * 设定vip
     * @param $uid
     * @param $gid
     * @param $price
     * @param bool $isDebug
     * Created by: Owen
     * Created on: 2020/7/21 18:17
     */
    public function changeVipStatus($uid,$gid,$price,$isDebug = false){
        $num = intval($price*100);
        if($gid == 601){
            $num += 50;
        }
        if($isDebug){
            if($gid == 801){
                oo::commonOprModel('newvip')->setFreeVip($uid,7*24*60*60);
            }else if($gid == 803){
                oo::commonOprModel('newvip')->setFreeVip($uid,30*24*60*60);
            }
//            oo::async()->add('oo::commonOprModel("notice")->sendNoticeMsg',[$uid,"buyVip"]);//异步跑马灯消息
        }
        oo::commonOprModel('newvip')->updateUserCurPoint($uid,$num);
        oo::commonOprModel('newvip')->updateVipLv($uid);
        oo::commonOprModel('Workerman')->push($uid,ocmd::$send['Vip_Rec'],['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);

        /**
         * ta 公共属性
         */
        $curVipLevel = oo::commonOprModel('newvip')->getUserVipLv($uid, false,false,155);
        $curVipScore = oo::commonOprModel('newvip')->getUserCurPoint($uid);
        $total = $this->getUserTotalPayNum($uid);
        oo::commonOprModel('ta')->setCommonEventProperty($uid,'common',['current_vip_level'=>$curVipLevel,'total_pay'=> $total]);
        oo::commonOprModel('ta')->setEventData($uid,'user_set',["total_pay"=>$total,"current_vip_level"=>$curVipLevel,"current_vip_score"=>$curVipScore,"last_pay_time"=>time()]);
    }

    /**
     * 商品数据后端转换前端格式
     * @param $data
     * @return mixed
     * Created by: Owen
     * Created on: 2020/7/21 18:37
     */
    public function goodDataTurnToFormat($data){
        if(isset($data['data']['money']) && !isset($data['data']['coins'])){
            $data['data']['coins'] = $data['data']['money'];
        }
        if(isset($data['data']['props'])){
            foreach ($data['data']['props'] as $row){
                if($row['propsId'] == 8 && !isset($data['data']['petExp'])){
                    $data['data']['petExp'] = $row['num'];
                }
                if($row['propsId'] == 9 && !isset($data['data']['petFeed'])){
                    $data['data']['petFeed'] = $row['num'];
                }
                if($row['propsId'] <= 4){
                    $data['data']['chest'][] = [
                        'chestId' => $row['propsId'],
                        'num'     => $row['num'],
                    ];
                }
            }
        }
        return $data;
    }

    /**
     * IOS 账号转移,转移订阅状态
     * @param $uid
     * @param $transactionId
     * @param $receipt
     * @return string
     * Created by: Owen
     * Created on: 2020/12/3 17:57
     */
    public function syncIosSubscribe($uid,$transactionId,$receipt){
        $tb  = otable::summarylist();
        $ret = oo::commonOprDb('payment')->getOne("SELECT * FROM {$tb} WHERE `sl_platform_serial_num`='{$transactionId}' LIMIT 1",MYSQLI_ASSOC);
        if(empty($ret)){
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_TRANSACTIONID_ERROR);
        }
        $applePayInfo = oo::commonOprModel('paymentapple')->validateApplePay(['uid'=>$uid,'receipt'=>$receipt,'transactionId'=>$transactionId],'original_transaction_id');
        if(!$applePayInfo){
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_ORDER_ERROR);
        }
        $id     = $ret['id'];
        $origUid= $ret['sl_uid'];
        $expire   = ceil($applePayInfo['expires_date_ms']/1000);
        if($origUid == $uid){
            oo::commonOprModel('member')->getUserInfo($uid, NULL, TRUE,[
                'svip' => 1,
                'svip_expire' => $expire,
            ]);
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_UID_ERROR,['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid),"expires_date_ms"=>$expire]);
        }
        oo::commonOprModel('member')->getUserInfo($origUid, NULL, TRUE,['svip'=>0]);
        oo::commonOprDb('payment')->query("UPDATE {$tb} SET `sl_uid` = '{$uid}' WHERE id={$id} AND `sl_platform_serial_num`='{$transactionId}' LIMIT 1",false);
        oo::commonOprModel('member')->getUserInfo($uid, NULL, TRUE,['svip'=>1,'svip_expire'=>$expire]);
        $tb = otable::SubscribeTransferLog();
        $subscribeInfo = json_encode([
            'localOrderInfo' => $ret,
            'appleOrderInfo' => $applePayInfo,
        ],JSON_NUMERIC_CHECK);
        $subscribeInfo = addslashes($subscribeInfo);
        oo::commonOprDb('common')->query("INSERT INTO {$tb} (id, origUid, newUid, subscribeInfo) VALUES(NULL,{$origUid},{$uid},'{$subscribeInfo}')",false);

        return oo::response(errorCode::SUCCESS,['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);
    }


    public function syncAndroidSubscribe($uid,$googleOrderId,$token){
        $sumTb  = otable::summarylist();
        $localOrderInfo = oo::commonOprDb('payment')->getOne("SELECT * FROM {$sumTb} WHERE `sl_platform_serial_num`='{$googleOrderId}' LIMIT 1",MYSQLI_ASSOC);
        if(empty($localOrderInfo)){
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_TRANSACTIONID_ERROR);
        }
        $origUid = $localOrderInfo['sl_uid'];
        $gid     = $localOrderInfo['sl_gid'];
        $tb      = otable::goodsCrazy();
        $goodInfo= oo::commonOprDb('common')->getOne("SELECT * FROM {$tb} WHERE gid={$gid} LIMIT 1",MYSQLI_ASSOC);
        $sku     = $goodInfo['gsku'];
        oo::commonOprRedis('common')->delete($token);
        $purchaseInfo= oo::commonOprModel('Paymentgoogle')->getUserSubscribeStatus("com.unioncity.crazycoin",$sku,$token);
        $expire      = ceil($purchaseInfo['expiryTimeMillis']/1000);
        if(isset($purchaseInfo['error'])){
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_UID_ERROR,['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);
        }
        if($origUid == $uid){
            oo::commonOprModel('member')->getUserInfo($uid, NULL, TRUE,[
                'svip' => 1,
                'svip_expire' => $expire,
            ]);
            oo::commonOprModel('ta')->setEventData($uid,'user_set',["is_member"=>1,"member_time"=>$expire]);
            return oo::response(errorCode::SYNCIOSSUBSCRIBE_UID_ERROR,['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);
        }
        $id      = $localOrderInfo['id'];
        oo::commonOprDb('payment')->query("UPDATE {$sumTb} SET `sl_uid` = '{$uid}' WHERE id={$id} AND `sl_platform_serial_num`='{$googleOrderId}' LIMIT 1",false);
        $subTb  = otable::subscription();
        oo::commonOprDb('payment')->query("UPDATE {$subTb} SET `uid`={$uid} WHERE `purchaseToken`='{$token}'",false);

        /**
         * 取消原本的用户的vip
         */
        oo::commonOprModel('member')->getUserInfo($origUid, NULL, true,[
            'svip'        => 0,
            'svip_expire' => time(),
        ]);
        /**
         * 设置新用户原本的用户的vip
         */
        oo::commonOprModel('member')->getUserInfo($uid, NULL, true,[
            'svip'        => 1,
            'svip_expire' => $expire,
        ]);

        /**
         * 同步奖励领取限制
         */
        if(oo::commonOprRedis('common')->get(okeys::UserVipWeekReward($origUid))){
            oo::commonOprRedis('common')->setex(okeys::UserVipWeekReward($uid),1,oo::todayDeadline());
        }

        $tb = otable::SubscribeTransferLog();
        $subscribeInfo = json_encode([
            'localOrderInfo' => $localOrderInfo,
            'appleOrderInfo' => $purchaseInfo,
        ],JSON_NUMERIC_CHECK);
        $subscribeInfo = addslashes($subscribeInfo);
        oo::commonOprDb('common')->query("INSERT INTO {$tb} (id, origUid, newUid, subscribeInfo) VALUES(NULL,{$origUid},{$uid},'{$subscribeInfo}')",false);
        oo::commonOprModel('ta')->setEventData($uid,'user_set',["is_member"=>1,"member_time"=>$expire]);
        return oo::response(errorCode::SUCCESS,['vipInfo'=>oo::commonOprModel('newvip')->getVipInfo($uid)]);
    }


}
