PacketrecordService.class.php 10.8 KB
<?php
/**
 * PacketService.class.php
 * 红包主表
 * User: yingcai
 * Date: 2017年03月16日
 */

namespace Common\Service;

use Common\Common\Cache;
use Common\Common\Sms;
use Common\Common\User;
use Common\Model\ActivityModel;
use Common\Model\PacketModel;
use Common\Model\PacketrecordModel;
use Think\Log;
use VcySDK\WxQy\Pay;

class PacketrecordService extends AbstractService
{

    // 红包领取成功
    const PACKET_SUCCESS = 1;
    // 红包已领取完
    const PACKET_NO = 2;
    // 用户已经领取过红包
    const PACKET_ALREADY = 4;
    // 系统错误
    const PACKET_SYS_ERR = 5;
    // 待支付
    const PAY_STATUS_WAITING = 1;
    // 支付完成
    const PAY_STATUS_END = 2;
    // 支付失败
    const PAY_STATUS_FAIL = 3;
    // 支付成功
    const PAY_STATUS_SUCCESS = 4;
    // 支付处理中
    const PAY_STATUS_ING = 5;
    // 支付超时
    const PAY_TIMEOUT = 6;

    /*
     * @var PacketModel 红包配置model
     */
    protected $_d_packet;

    /**
     * 构造方法
     */
    public function __construct()
    {
        parent::__construct();
        $this->_d = new PacketrecordModel();
        $this->_d_packet = new PacketModel();
    }

    /**
     * [拆红包操作]
     *
     * @param  array $detail [红包详情数据]
     *
     * @return int $pk_status    [拆红包状态]
     */
    public function split_packet($detail = [])
    {
        // 初始化数据
        $pk_status = self::PAY_STATUS_FAIL;

        Log::write('------进入支付方法-------');
        // 获取应用名称
        $application_name = cfg('APPLICATION_NAME');

        // 支付参数
        $pay_params = [
            'uid' => $detail['uid'],
            'checkName' => 'NO_CHECK',
            'reUserName' => $detail['username'],
            'platformOrderNo' => $detail['order_sn'],
            'amount' => $detail['rand_money'],
            'actName' => strval($application_name)
        ];

        Log::write('------支付参数-------');
        Log::write(var_export($pay_params, true));

        // 实例化支付类
        $pay_service = new Pay(\VcySDK\Service::instance());
        // 调用支付
        Log::write('------调用支付-------');
        $call_pay = $pay_service->pay($pay_params);
        Log::write('------支付返回参数-------');
        Log::write(var_export($call_pay, true));
        $wtlPartnerTradeNo = $call_pay['wtlPartnerTradeNo'];

        // 将支付平台内部订单号与该订单关联
        $this->_d->update($detail['rid'], ['wtlPartnerTradeNo' => $wtlPartnerTradeNo]);

        Log::write('------查看支付结果-------');
        // 查看支付结果
        $pay_result = $pay_service->payResult($wtlPartnerTradeNo);
        Log::write(var_export($pay_result, true));
        // 初始化循环执行时间
        $run_time = NOW_TIME;
        // 支付中去轮询查询支付结果
        while ($pay_result[0]['wtlPayStatus'] == self::PAY_STATUS_WAITING) {

            $termin_time = NOW_TIME;

            // 循环是否超时
            if ($termin_time - $run_time > 3) {
                // 支付请求超时
                return self::PAY_TIMEOUT;

                break;
            }

            $pay_result = $pay_service->payResult($call_pay['wtlPartnerTradeNo']);

            // 挂起500ms
            usleep(500000);
        }

        // 如果领取失败
        if ($pay_result[0]['wtlPayStatus'] != self::PAY_STATUS_END
            && $pay_result[0]['wtlPayStatus'] != self::PAY_STATUS_SUCCESS) {

            Log::write('------领取失败-------');

            Log::write(var_export($pay_result[0], true));
            // 企业余额是否充足
            if ($pay_result[0]['wtlErrCode'] == 'NOTENOUGH') {
                Log::write('------账户余额不足-------');
                $message = '【畅移信息】您的微信企业号余额不足,红包发放失败,请您尽快充值!';

                $packet_m = new PacketModel();
                // 查询提醒电话号码
                $packet = $packet_m->get_by_conds(['ac_id' => $detail['ac_id']]);

                // 初始化缓存字段名称
                $file_name = 'Common.Sale_Msg_' . $detail['ac_id'] . '_' . $packet['warn_mobile'];

                // 初始化缓存类
                $Cache = &Cache::instance();

                try {
                    $Cache->get($file_name);
                } catch (\Exception $e) {
                    // 给提醒号码发短信
                    Sms::instance()->send($packet['warn_mobile'], $message);

                    $Cache->set($file_name, $packet['warn_mobile'], ['expire' => 7200]);
                }
            }

            // 红包领取记录表更新数据
            $update_record_data = [
                'packet_status' => self::PACKET_STATUS_FAIL, // 领取失败
                'receive_time' => MILLI_TIME, // 领取时间
            ];

            // 更新红包领取记录表数据领取状态
            $this->_d->update($detail['rid'], $update_record_data);

            return self::PAY_STATUS_FAIL;
        }

        if ($pay_result[0]['wtlPaymentNo']) {
            Log::write('------支付成功-------');
            Log::write(var_export($pay_result[0], true));
            // 支付成功
            try {
                // 开启事务
                $this->start_trans();

                // 红包领取记录表更新数据
                $update_record_data = [
                    'packet_status' => self::PACKET_STATUS_SUCCESS, // 领取成功
                    'receive_time' => MILLI_TIME,
                    'wtlDetailId' => strval($pay_result[0]['wtlDetailId']),
                    'wtlPaymentNo' => strval($pay_result[0]['wtlPaymentNo']),
                    'wtlPlatformOrderNo' => strval($pay_result[0]['wtlPlatformOrderNo'])
                ];

                // 更新红包领取记录表数据
                $this->_d->update($detail['rid'], $update_record_data);

                // 支付成功
                $pk_status = self::PACKET_SUCCESS;

                $this->commit();
            } catch (\Think\Exception $e) {

                \Think\Log::record($e);
                // 事务回滚
                $this->_set_error($e->getMessage(), $e->getCode());
                $this->rollback();
                $pk_status = self::PACKET_SYS_ERR;
            } catch (\Exception $e) {

                \Think\Log::record($e);
                $this->_set_error($e->getMessage(), $e->getCode());
                // 事务回滚
                $this->rollback();
                $pk_status = self::PACKET_SYS_ERR;
            }
        }

        return $pk_status;
    }


    /**
     * 格式化红包领取记录列表
     *
     * @param array $list
     *
     * @return array
     */
    public function format_records_list($list = [])
    {

        // 初始化用户USER类
        $user = User::instance();
        $uids = array_column($list, 'uid');

        // 查询所有用户包含已删除用户信息
        $user_list = $user->listUsersAll(['memUids' => $uids, 'memAll' => 1]);

        $record_list = [];

        foreach ($list as $v) {

            $user_info = $user_list[$v['uid']];

            $record_list[] = [
                'uid' => $v['uid'],
                'avatar' => $user->avatar($v['uid'], $user_info),
                'username' => $user_info['memUsername'],
                'receive_time' => $v['receive_time'],
                'rand_money' => sprintf("%.2f", $v['rand_money'] / 100), // 转换为元
            ];
        }

        return $record_list;
    }


    /**
     * 红包补发
     *
     * @param array $record_info 原红包记录数据
     * @param array $admin 管理员信息
     * @param array $activity 活动信息
     *
     * @return bool
     */
    public function regive_red($record_info = [], $admin = [], $activity = [])
    {

        try {
            // 开启事务
            $this->_d->start_trans();

            $give_time = MILLI_TIME; // 发放时间
            // 组装入库数据
            $record_arr = [
                'pid' => $record_info['pid'],
                'p_type' => $record_info['p_type'],
                'ac_id' => $record_info['ac_id'],
                'rand_money' => $record_info['rand_money'],
                'packet_status' => self::PACKET_STATUS_WAIT, // 领取状态为:待领取
                'give_time' => $give_time, // 发放时间
            ];


            // 插入红包记录
            $rid = (int)$this->_d->insert($record_arr);

            // 组装更新数据,主要是为了更新订单id以及与用户的关联关系
            $update_arr = [
                'cid' => $record_info['cid'],
                'order_sn' => $this->get_order_sn(3, $rid), // 生成订单号
                'uid' => $record_info['uid'],
                'send_uname' => $admin['eaRealname'],  // 发放人
                'send_phone' => $admin['eaMobile'], // 发放人电话
                'username' => $record_info['username'],
                'parent_rid' => $record_info['rid'], // 补发的红包id
            ];
            // 更新订单记录数据
            $total = $this->_d->update($rid, $update_arr);

            // 将原红包记录改为已补发
            $num = $this->_d->update($record_info['rid'], ['packet_status' => self::PACKET_STATUS_REPEAT]);

            // 订单记录或者已补发红包记录失败
            if (!$total || !$num) {
                
                $this->_d->rollback();
                return false;
            }

            // 提交事务
            $this->_d->commit();

        } catch (\Think\Exception $e) {
            \Think\Log::record($e);
            // 事务回滚
            $this->_d->rollback();
            return false;
        } catch (\Exception $e) {
            \Think\Log::record($e);
            // 事务回滚
            $this->_d->rollback();
            return false;
        }

        if (empty($activity)) {
            // 实例化活动表
            $activity_m = new ActivityModel();
            // 获取活动信息
            $activity = $activity_m->get($record_info['ac_id']);
        }

        // 组织发消息参数
        $params = [
            'give_time' => $give_time,
            'subject' => $activity['subject'],
            'rid' => $rid,
            'ac_id' => $record_info['ac_id'],
            'uids' => $record_info['uid'],  // 接收消息人员
            'rand_money' => $record_info['rand_money']  // 金额
        ];

        // 此处发消息
        if (self::RED_PACKET_RAND == $record_info['p_type']) {
            // 补发随机红包
            $this->send_msg($params, self::MSG_GET_REPEAT_RANDOM_REDPACKET);
        } elseif (self::RED_PACKET_VIP == $record_info['p_type']) {
            // 补发定向红包
            $this->send_msg($params, self::MSG_GET_REPEAT_VIP_REDPACKET);
        }

        return true;
    }

}