<?php

/**
 * 刷新充值订单(领取充值结果) , 客户端收到SDK成功支付返回的订单号后,请求游戏服务器发货,
 * 游戏服务器拿订单号和uid、zoneid一起来pay_op验证订单,如果验证通过, 会主动调用发货方法,
 * 请游戏发货方法成功返回true,失败返回false. 本方法后续逻辑会判断游戏服务器是否发货成功,
 * 发货成功的化,会更新订单的领取状态.
 * 用法:
 *
 *   require_once dirname(__FILE__) . '/../../../public/sdk/official/pay/pay_op.php';
 *   use loyalsoft\pay_op;
 *
 *   pay_op::CheckAndDrawOrders($uid, $deliverFunc);
 *
 */

namespace loyalsoft;

require_once __DIR__ . '/../../../main.php';                                    # 导入基础库

class pay_op {

    const orderTab = 'tpl_order_tab';                                           # 订单表表名

    /**
     *  刷新充值订单(领取充值结果) , 客户端收到SDK成功支付返回的订单号后,请求游戏服务器发货,
     * 游戏服务器拿订单号和uid、zoneid一起来pay_op验证订单,如果验证通过, 会主动调用发货方法,
     * 请游戏发货方法成功返回true,失败返回false. 本方法后续逻辑会判断游戏服务器是否发货成功,
     * 发货成功的化,会更新订单的领取状态.
     * 本方法 全部执行完毕返回 err=0, 任意步骤 出现错误会返回相应的错误码.
     * 游戏服务器调用本方法后注意判断返回值,err==0,代表一切正常, 否则请放弃本次执行结果.
     * @version  2020年1月2日   第二版 去掉了zoneid参数, 订单编号长度从16位改为19位.
     *            2019年12月11日 第一版  --gwang
     * @author gwang<wanggangzero@qq.com>
     * @param type $uid

     * @param type $cpOrderId
     * @param bool function $deliverFunc 发货成功返回 true,否则返回false
     * @return {"err":0,"ret":obj,"msg":"错误信息"}
     * @deprecated since version 0 使用CheckAndDrawOrders
     */
    static function CheckAndDrawOrder($uid, $cpOrderId, $deliverFunc) {
        if (!$uid || strlen($cpOrderId) != 19) {                                # 订单编号长19位
            return Resp::err(1, "参数错误");
        }
        $order = daoInst()->select()->from(self::orderTab)                      # 取订单数据
                        ->where('cpOrderId')->eq($cpOrderId)
                        ->limit(1)->fetch();
        if (!$order) {
            CLog::pay(' 订单不存在! ' . $cpOrderId);
            return Resp::err(2, "订单不存在");
        }
        if (false === strpos($uid, $order->uid)) {                              # UID不符
            return Resp::err(3, "UID不符");
        }

        if ($order->channel != "imitate" #                                      # 校验是否已支付的代码, -- imitate的不校验
                && $order->status != 1) {                                       # 订单状态
            CLog::pay(' 订单尚未完成支付!');
            return Resp::err(4, "订单尚未完成支付");
        }

        if ($order->drawed_ts > 0) {                                            # 定单已经发过货了
            CLog::pay(' 订单重复请求发货!' . $cpOrderId);
            return Resp::err(5, "订单重复请求发货");
        }
        if (!is_callable($deliverFunc)) {                                       # 校验回调函数是否可执行
            CLog::pay('发货回调函数不是可执行对象!' . $cpOrderId);
            return Resp::err(6, "发货函数不可调用!");
        }

        $bOk = call_user_func($deliverFunc, $order);                            # 调用游戏发货逻辑, 要求游戏逻辑返回true/false
        if (!$bOk) {
            CLog::pay("订单发货失败: $cpOrderId");
            return Resp::err(7, "游戏发货逻辑执行失败");
        }
        $n = daoInst()->update(self::orderTab)                                  # 更新订单状态
                ->data(array('drawed_ts' => now()))
                ->where('cpOrderId')->eq($cpOrderId)
                ->exec();
        if (!$n) {
            CLog::pay("数据库更新订单状态失败: $cpOrderId");
            return Resp::err(8, "更新订单状态,数据库操作失败");                   # 数据库操作失败
        }

        CLog::pay("订单发货成功: $cpOrderId");
        return Resp::ok("");
    }

    /**
     * 查询已支付未发货订单
     * @param string $uid 账号ID
     * @return array 订单编号数组
     * @version  2020年1月2日 第一版, 增加查询订单接口.流程上变为先查询订单再调用校验发货方法.
     */
    static function FindReadOrders($uid) {
        if (!$uid) {                                                            # uid不能为空
            return Resp::err("1", "参数错误");
        }
        $orders = daoInst()->select('cpOrderId')->from(pay_op::orderTab)        # 取订单数据
                        ->where('uid')->eq($uid)
                        ->andWhere('status')->eq(1)
                        ->andWhere('drawed_ts')->le(0)
                        ->limit(10)->fetchAll();                                # 一次最多返10条
        return $orders;
    }

}

//
//$orders = json_decode(json_encode(array(
//    array('Id' => 3),
//    array('Id' => 2)
//        )));
//$arrOrderId = array(1, 2);
//array_map(function($o)use(&$arrOrderId) {
//    $arrOrderId[] = $o->Id;
//}, $orders);
//var_dump($arrOrderId);
//$n = daoInst()->update(pay_op::orderTab)                                  # 更新订单状态
//        ->data(array('drawed_ts' => now()))
//        ->where('Id')->in($arrOrderId)
//        ->exec();
//$uid = "0BB6B1D602621423EBA082F17A57712F";
//$orders = daoInst()->select('cpOrderId')->from(pay_op::orderTab)        # 取订单数据
//                ->where('uid')->eq($uid)
//                ->andWhere('status')->eq(1)
//                ->andWhere('drawed_ts')->le(0)
//                ->limit(10)->fetchAll();                                # 一次最多返10条
//
//var_dump($orders);











