public function handle_request_internal() { $brokerId = $this->_params['brokerId']; $customerId = $this->_params['customerId']; // 升级提示 $rushStartTime = APF::get_instance()->get_config('v2_rush_customer_consume_coupon_time', 'customer'); if (time() >= strtotime($rushStartTime)) { return array('status' => 'error', 'message' => "抢客户功能大升级!快去最新版本移动经纪人APP中体验吧!"); } // 判断经纪人是否存在 $broker = Model_Broker_AjkBrokerExtend::findWithBrokerId($brokerId); if (!$broker) { throw new Exception_Broker_NotFound('BrokerId: ' . $brokerId); } // 判断经纪人和客户之间关系是否存在(当日内) $relation = Model_Mobile_BrokerUserRelation::getBrokerCustomerTodayRelation($brokerId, $customerId); if (!$relation) { throw new Exception_CustomerRush_RelationNotFound("BrokerId: {$brokerId}, CustomerId: {$customerId}"); } // 判断经纪人和客户是否已经有效锁定(未过期临时锁定 或 永久锁定) if ($relation->isLocked()) { throw new Exception_CustomerRush_IsLocked("BrokerId: {$brokerId}; CustomerId: {$customerId}; RelationId: {$relation->id}; Status: {$relation->status}; TempLockExpireTime: {$relation->tempLockExpireTime}"); } // 判断经纪人是否可抢 $brokerTodayLockTimes = Model_Mobile_BrokerUserRelation::getBrokerTodayLockTimes($brokerId); if ($brokerTodayLockTimes >= Const_CustomerRush::BROKER_MAX_RUSH_COUNT) { throw new Exception_CustomerRush_BrokerChanceUsedUp("BrokerId: {$brokerId};"); } // 检测用户是否屏蔽 if (!$relation->isCustomerAllowRush()) { throw new Exception_CustomerRush_CustomerNotAllowRush("BrokerId: {$brokerId}, CustomerId: {$customerId}"); } // 判断用户是否可抢 $customerTodayLockTimes = Model_Mobile_BrokerUserRelation::getCustomerTodayLockTimes($customerId); if ($customerTodayLockTimes >= Const_CustomerRush::CUSTOMER_MAX_RUSHED_COUNT) { throw new Exception_CustomerRush_CustomerChanceUsedUp("CustomerId: {$customerId};"); } // 获取经纪人锁 if (!Bll_Customer_Parallel::lockBroker($brokerId)) { throw new Exception_CustomerRush_LockBrokerFailed("BrokerId: {$brokerId}; CustomerId: {$customerId}; RelationId: {$relation->id};"); } // 获取客户锁 if (!Bll_Customer_Parallel::lockUser($customerId)) { Bll_Customer_Parallel::unlockBroker($brokerId); throw new Exception_CustomerRush_LockCustomerFailed("BrokerId: {$brokerId}; CustomerId: {$customerId}; RelationId: {$relation->id};"); } // 临时锁定,更新关系 $relation->tempLock(); // 临时锁定,更新锁定 Model_Mobile_CustomerLock::tempLock($relation->id, $relation->uploadDt, $relation->brokerId, $relation->userDeviceId); // 释放客户锁 Bll_Customer_Parallel::unlockUser($customerId); // 释放经纪人锁 Bll_Customer_Parallel::unlockBroker($brokerId); return array('status' => Const_APIStatus::RETURN_CODE_OK, 'data' => array('status' => 1, 'statusMsg' => '抢成功')); }
/** * @return array */ public function handle_request_internal() { $brokerId = $this->_params['broker_id']; $deviceId = $this->_params['device_id']; // 升级提示 $rushStartTime = APF::get_instance()->get_config('v2_rush_customer_consume_coupon_time', 'customer'); if (time() >= strtotime($rushStartTime)) { return array('status' => 'error', 'message' => "抢客户功能大升级!快去最新版中体验吧!"); } // 判断经纪人和客户之间关系是否存在(当日内) $relation = Model_Mobile_BrokerUserRelation::getBrokerCustomerTodayRelation($brokerId, $deviceId); if (!$relation) { throw new Exception_CustomerRush_RelationNotFound("BrokerId: {$brokerId}, CustomerId: {$deviceId}"); } /** 判断经纪人和用户是否已经是有效的临时绑定关系 */ if (Bll_Customer_BrokerUserRelation::checkBrokerUserRelationStatusIsBind($deviceId, $brokerId)) { return array('status' => 'ok', 'data' => array('success' => 1, 'description' => '经纪人和用户已经是锁定关系')); } if (false === Bll_Customer_Lock::checkBrokerCanBind($brokerId)) { return array('status' => 'ok', 'data' => array('success' => 0, 'description' => '经纪人锁定次数已经满3次了')); } if (false == Bll_Customer_Lock::checkUserCanBind($deviceId)) { return array('status' => 'ok', 'data' => array('success' => 0, 'description' => '用户锁定次数已经满3次了')); } /** 防并发 开始 */ if (false === Bll_Customer_Parallel::lockBroker($brokerId)) { return array('status' => 'ok', 'data' => array('success' => 0, 'description' => '经纪人并发锁失败')); } if (false === Bll_Customer_Parallel::lockUser($deviceId)) { Bll_Customer_Parallel::unlockBroker($brokerId); return array('status' => 'ok', 'data' => array('success' => 0, 'description' => '用户并发锁失败')); } // 临时锁定,更新关系 $relation->tempLock(); // 临时锁定,更新锁定 Model_Mobile_CustomerLock::tempLock($relation->id, $relation->uploadDt, $relation->brokerId, $relation->userDeviceId); Bll_Customer_Parallel::unlockBroker($brokerId); Bll_Customer_Parallel::unlockUser($deviceId); /** 防并发 结束 */ $result = array('status' => 'ok', 'data' => array('success' => 1)); return $result; }
public function handle_request_internal() { $brokerId = $this->_params['brokerId']; $customerId = $this->_params['customerId']; $result = array('status' => 'error', 'message' => ''); // 验证经纪人是否合法 $broker = Model_Broker_AjkBrokerExtend::findWithBrokerId($brokerId); if (!$broker) { $result['message'] = '经纪人不合法'; return $result; } // 判断是否已经抢过(永久锁定) $lock = Bll_CustomerRush_Lock::getDataByBrokerIdAndCustomerId($brokerId, $customerId); if (!empty($lock)) { $result['message'] = '已经被抢过了'; return $result; } // 判断是否有临时关系 $date = date('Y-m-d', strtotime("-2 day")); $relation = Bll_CustomerRush_BrokerUserRelation::getInstance()->getLastRalationData($brokerId, $customerId, $date); if (!$this->_isTmpRelation($relation) || empty($relation)) { $result['message'] = '已超时,请重新抢我'; return $result; } if (!$this->_isFree()) { // 获取最早的一张可用劵数据 $coupon = Bll_CustomerRush_Coupon::getInstance()->getBrokerOldestCouponEx($brokerId); if (empty($coupon) || $coupon->totalNum <= $coupon->usedNum) { $result['message'] = '没有可抢次数'; return $result; } } // 获取经纪人锁 if (!Bll_Customer_Parallel::lockBroker($brokerId)) { $result['message'] = '锁经纪人异常'; return $result; } /* * 兼容5.0版本 ,先判断coustomer_locks表中是否有临时性数据,如果有数据则更新,否则新增插入 */ $latestTryLock = Model_Mobile_CustomerLock::getV2BrokerCustomerLatestTempLock($brokerId, $customerId, $relation->uploadDt); if (empty($latestTryLock)) { // 插入永久锁定 $insertCusomerLockData = array('uploadDt' => $relation->uploadDt, 'relationId' => $relation->brokerUserRelationId, 'brokerId' => $brokerId, 'userDeviceId' => $customerId, 'status' => 2, 'foreverLockTime' => date("Y-m-d H:i:s"), 'createTime' => date("Y-m-d H:i:s"), 'updateTime' => date("Y-m-d H:i:s")); Bll_CustomerRush_Lock::insertCustomerLock($insertCusomerLockData); } else { // 更新customer_locks表 $latestTryLock->relationId = $relation->brokerUserRelationId; $latestTryLock->status = 2; $latestTryLock->foreverLockTime = date("Y-m-d H:i:s"); $latestTryLock->updateTime = date("Y-m-d H:i:s"); $latestTryLock->save(); } if (!$this->_isFree()) { // 消耗劵 $this->_updateBrokerCoupon($coupon); } // 更新永久锁定,加1 Bll_CustomerRush_Lock::incrForeverLockCount($brokerId, 1); // 更新临时表的关系 $relation->status = Model_Mobile_BrokerUserRelationSub::STATUS_FOREVER_LOCKED; $relation->updateTime = date("Y-m-d H:i:s"); $relation->tempLockTime = '0000-00-00 00:00:00'; $relation->tempLockExpireTime = '0000-00-00 00:00:00'; $relation->save(); // 释放经纪人锁 Bll_Customer_Parallel::unlockBroker($brokerId); $result['status'] = 'ok'; $result['message'] = '成功'; return $result; }
public function __destruct() { if ($this->needReleaseLock) { Bll_Customer_Parallel::unlockBroker($this->_params['broker_id']); Bll_Customer_Parallel::unlockUser($this->_params['device_id']); } parent::__destruct(); }
public function handle_request_internal() { $brokerId = $this->_params['brokerId']; $customerId = $this->_params['customerId']; $chatBody = $this->_params['chatBody']; $authToken = $this->_params['authToken']; // 判断经纪人是否存在 $broker = Model_Broker_AjkBrokerExtend::findWithBrokerId($brokerId); if (!$broker) { throw new Exception_Broker_NotFound('BrokerId: ' . $brokerId); } // 获取有效临时锁定存在 $relation = Model_Mobile_BrokerUserRelation::getBrokerCustomerLatestTempLockRelation($brokerId, $customerId); if (!$relation) { // 如无临时锁定,获取有永久锁定存在 $relation = Model_Mobile_BrokerUserRelation::getBrokerCustomerLatestForeverLockRelation($brokerId, $customerId); if (!$relation) { // 关系不存在时,提示:客户失效了 重新抢吧 throw new Exception_CustomerRush_RelationNotFound("BrokerId: {$brokerId}, CustomerId: {$customerId}"); } } // TODO 微聊好友(如何根据 DeviceId 和 BrokerId 判断好友关系,有接口吗?) // 如果客户禁止抢 if (!$relation->isCustomerAllowRush()) { throw new Exception_CustomerRush_CustomerNotAllowRush("BrokerId: {$brokerId}, CustomerId: {$customerId}"); } // 控制当日发送的微聊消息数量 if (Bll_CustomerRush_Chat::isChatSendCountLimitEnabled()) { $chatCountDailyLimit = Bll_CustomerRush_Chat::getChatSendCountDailyLimit(); $todayChatCount = Bll_CustomerRush_Chat::getTodayChatCount($brokerId, $customerId); if ($todayChatCount >= $chatCountDailyLimit) { throw new Exception_CustomerRush_TooManyChat("Today Count: {$todayChatCount}; Daily Limit: {$chatCountDailyLimit}"); } } // 格式化输入的参数:chatBody if (!is_array($chatBody)) { $chatBody = json_decode($chatBody, true); } // 判断是否是第一次发送 if (Bll_CustomerRush_Chat::isFirstChat($brokerId, $customerId)) { $chatBody['first_send'] = 1; } // 永久锁定,发消息即可 if ($relation->isForeverLocked()) { // 发送微聊消息 $chatResponse = Bll_CustomerRush_Chat::sendAppMessage($authToken, $chatBody); // 保存微聊记录 Bll_CustomerRush_Chat::saveChat($brokerId, $customerId, $chatBody); } else { // 临时锁定,发消息,更新状态 // 获取经纪人锁 if (!Bll_Customer_Parallel::lockBroker($brokerId)) { throw new Exception_CustomerRush_LockBrokerFailed("BrokerId: {$brokerId}; CustomerId: {$customerId}; RelationId: {$relation->id};"); } // 获取客户锁 if (!Bll_Customer_Parallel::lockUser($customerId)) { Bll_Customer_Parallel::unlockBroker($brokerId); throw new Exception_CustomerRush_LockCustomerFailed("BrokerId: {$brokerId}; CustomerId: {$customerId}; RelationId: {$relation->id};"); } // 发送微聊消息 $chatResponse = Bll_CustomerRush_Chat::sendAppMessage($authToken, $chatBody); // 保存微聊记录 Bll_CustomerRush_Chat::saveChat($brokerId, $customerId, $chatBody); // 更新关系,临时锁定->永久锁定 $relation->foreverLock(); // 更新锁定,临时锁定->永久锁定 Model_Mobile_CustomerLock::foreverLock($relation->id, $relation->uploadDt, $relation->brokerId, $relation->userDeviceId); // 更新永久锁定,加1 Bll_CustomerRush_Lock::incrForeverLockCount($brokerId, 1); // 释放客户锁 Bll_Customer_Parallel::unlockUser($customerId); // 释放经纪人锁 Bll_Customer_Parallel::unlockBroker($brokerId); } return array('status' => Const_APIStatus::RETURN_CODE_OK, 'data' => array('status' => 1, 'statusMsg' => '成功', 'msgId' => $chatResponse['msg_id'])); }
/** * 初始化Redis连接 * * @throws RedisException */ private static function initRedis() { $apf = APF::get_instance(); $config = $apf->get_config('mobile_customer', 'redis'); if (!isset($config['host']) || !isset($config['port'])) { throw new RedisException('Host and port are needed to connect redis server.'); } self::$redis = new Redis(); if (!self::$redis->connect($config['host'], $config['port'])) { throw new RedisException("Failed to connect redis server: {$config['host']}:{$config['port']}"); } }
public function handle_request_internal() { $brokerId = $this->_params['brokerId']; $customerId = $this->_params['customerId']; $result = array('status' => 'error', 'message' => ''); // 验证经纪人是否合法 $broker = Model_Broker_AjkBrokerExtend::findWithBrokerId($brokerId); if (!$broker) { $result['message'] = '经纪人不合法'; return $result; } // 判断经纪人和客户之间关系是否存在(三日内) $date = date('Y-m-d', strtotime("-2 day")); $relation = Bll_CustomerRush_BrokerUserRelation::getInstance()->getLastRalationData($brokerId, $customerId, $date); if (empty($relation)) { $result['message'] = '不存在数据关系'; return $result; } // 检测用户是否屏蔽 if (!Bll_CustomerRush_BrokerUserRelation::getInstance()->isCustomerAllowRush($relation)) { $result['message'] = '用户已屏蔽'; return $result; } // 判断是否已经抢过(永久锁定) $lock = Bll_CustomerRush_Lock::getDataByBrokerIdAndCustomerId($brokerId, $customerId); if (!empty($lock)) { $result['message'] = '已经被抢过了'; return $result; } // 判断是否存在临时关系 if ($relation->status != Model_Mobile_BrokerUserRelationSub::STATUS_TEMP_LOCKED) { // 不存在临时关系,建立临时关系 // 判断是否已经满3次 $tmpDate = date("Ymd"); $rushedCountData = Bll_CustomerRush_Customer::getInstance()->getCustomerRushedCount($customerId, $tmpDate); $limit = APF::get_instance()->get_config('customer_day_rushed_limit', 'customer'); if (!empty($rushedCountData) && $rushedCountData[0]['num'] >= $limit) { $result['message'] = '已经被抢完了'; return $result; } // 获取经纪人锁 if (!Bll_Customer_Parallel::lockBroker($brokerId)) { $result['message'] = '锁经纪人异常'; return $result; } // 获取客户锁 if (!Bll_Customer_Parallel::lockUser($customerId)) { Bll_Customer_Parallel::unlockBroker($brokerId); $result['message'] = '锁客户异常'; return $result; } // 更新关系 $updateRelationSub = array('status' => Model_Mobile_BrokerUserRelationSub::STATUS_TEMP_LOCKED, 'tempLockTime' => date("Y-m-d H:i:s"), 'tempLockExpireTime' => date('Y-m-d H:i:s', strtotime('+' . Model_Mobile_BrokerUserRelationSub::TEMP_LOCK_PERIOD . ' mins')), 'updateTime' => date("Y-m-d H:i:s")); Bll_CustomerRush_BrokerUserRelation::getInstance()->updateBrokerUserRelationSub(array('id' => $relation->id), $updateRelationSub); // 每日被抢加+1 Bll_CustomerRush_Customer::getInstance()->addCustomerRushedCount($customerId); // 释放客户锁 Bll_Customer_Parallel::unlockUser($customerId); // 释放经纪人锁 Bll_Customer_Parallel::unlockBroker($brokerId); } // 创建支付中心账户id Bll_Customerrush_Payment_User::getInstance()->getUserAccountId($brokerId, $broker['userId']); // 查询有无未激活的活动劵 $activeCoupon = Bll_CustomerRush_Coupon::getInstance()->getActiveCouponByBrokerId($brokerId, Model_Mobile_CustomerBrokerCouponActivity::STATUS_CREATE); if (!empty($activeCoupon) && $this->_isActivity()) { // 获取劵信息 $coupon = Bll_CustomerRush_Coupon::getInstance()->getCouponById($activeCoupon['couponId']); $result['data']['unActiveCouponNum'] = !empty($coupon) ? $coupon[0]['totalNum'] : 0; } else { $result['data']['unActiveCouponNum'] = 0; } // 查询可抢次数 $rushTimedata = Bll_CustomerRush_Coupon::getInstance()->getRushTime($brokerId, Model_Mobile_CustomerBrokerCoupon::STATUS_OK_USE); if ($rushTimedata['status'] == 'ok') { $result['data']['canRushTime'] = $rushTimedata['amount']; } else { $result['data']['canRushTime'] = 0; } $result['data']['useCouponNum'] = 1; $result['data']['relation'] = 1; $baseActiveUrl = APF::get_instance()->get_config('activity_coupon_active_url', 'customer'); $result['data']['activeUrl'] = $baseActiveUrl . "?brokerid=" . $brokerId; $result['status'] = 'ok'; $result['message'] = '建立临时性关系'; $result['data']['customerId'] = $customerId; // 收费开关配置 if ($this->_isFree()) { $result['data']['status'] = 1; // 免费 } else { if ($result['data']['useCouponNum'] <= $result['data']['canRushTime']) { $result['data']['status'] = 2; // 有劵,去消耗劵 } else { $result['data']['status'] = 3; // 劵剩余不足 } } return $result; }