/**
  * @args {"description": "Delay: Stats of StatsMemberGrowthMonthly every day"}
  * @author Rex Chen
  */
 public function perform()
 {
     $args = $this->args;
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m', $datetime);
     $startTime = new \MongoDate(strtotime($dateStr . '-01'));
     $endTime = new \MongoDate(strtotime($dateStr . '-01 +1 month'));
     $accounts = Account::findAll(['enabledMods' => 'member']);
     foreach ($accounts as $account) {
         $accountId = $account->_id;
         $totalMember = Member::countByAccount($accountId, null, $endTime);
         $totalActive = MemberLogs::getTotalActiveByAccount($accountId, $startTime, $endTime);
         $totalNew = Member::countByAccount($accountId, $startTime, $endTime);
         $statsGrowth = ModelStatsMemberGrowthMonthly::getByMonthAndAccount($accountId, $dateStr);
         if (empty($statsGrowth)) {
             $statsGrowth = new ModelStatsMemberGrowthMonthly();
             $statsGrowth->accountId = $accountId;
             $statsGrowth->month = $dateStr;
         }
         $statsGrowth->totalNew = $totalNew;
         $statsGrowth->totalActive = $totalActive;
         $statsGrowth->totalInactive = $totalMember - $totalActive;
         try {
             $statsGrowth->save();
         } catch (Exception $e) {
             ResqueUtil::log(['Update StatsMemberGrowthMonthly error' => $e->getMessage(), 'StatsMemberGrowthMonthly' => $statsGrowth]);
             continue;
         }
     }
     return true;
 }
 /**
  * @args {"description": "Delay: Stats of StatsMemberDaily", "runNextJob": true}
  * @author Rex Chen
  */
 public function perform()
 {
     $args = $this->args;
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     if (!empty(WECONNECT_DOMAIN)) {
         $channelNameMap = $this->_getChannelNameMap();
     }
     $start = new \MongoDate($datetime);
     $end = new \MongoDate(strtotime('+1 day', $datetime));
     $memberStats = Member::getNewMemberStats($start, $end);
     $rowStats = [];
     foreach ($memberStats as $stats) {
         $accountId = $stats['_id']['accountId'];
         $origin = $stats['_id']['origin'];
         $socialAccountId = $stats['_id']['socialAccountId'];
         $originName = empty($channelNameMap[$socialAccountId]) ? '' : $channelNameMap[$socialAccountId];
         $total = $stats['total'];
         $statsMember = ModelStatsMemberDaily::getByDateAndOriginInfo($dateStr, $origin, $originName, $accountId);
         if (!empty($statsMember)) {
             $statsMember->total = $total;
             try {
                 $statsMember->save(true, ['total']);
             } catch (Exception $e) {
                 ResqueUtil::log(['Update StatsMemberDaily error' => $e->getMessage(), 'StatsMemberDaily' => $statsMember]);
                 continue;
             }
         } else {
             $rowStats[] = ['date' => $dateStr, 'origin' => $origin, 'originName' => $originName, 'total' => $total, 'accountId' => $accountId];
         }
     }
     ModelStatsMemberDaily::batchInsert($rowStats);
     return true;
 }
 /**
  * @args {"description": "Delay: Stats of questionnaire"}
  */
 public function perform()
 {
     $args = $this->args;
     //Get date from args or today
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     $stats = QuestionnaireLog::getStats($dateStr);
     $statsRows = [];
     foreach ($stats as $stat) {
         $questionnaireId = $stat['_id']['questionnaireId'];
         $accountId = $stat['_id']['accountId'];
         //if $dailyStats exists, update it; else , create
         $dailyStats = ModelStatsQuestionnaireDaily::getByQuestionnaireAndDate($accountId, $questionnaireId, $dateStr);
         if (empty($dailyStats)) {
             $statsRows[] = ['accountId' => $accountId, 'questionnaireId' => $questionnaireId, 'date' => $dateStr, 'count' => $stat['count']];
         } else {
             $dailyStats->count = $stat['count'];
             //catch exception to avoid block batch insert
             try {
                 $dailyStats->save(true, ['count']);
             } catch (Exception $e) {
                 LogUtil::error(['Update StatsQuestionnaireDaily error' => $e->getMessage(), 'StatsQuestionnaireDaily' => $dailyStats]);
                 continue;
             }
         }
     }
     ModelStatsQuestionnaireDaily::batchInsert($statsRows);
     return true;
 }
Beispiel #4
0
 /**
  * @args {"description": "Delay: Clean offline client and helpdesk every minute"}
  */
 public function perform()
 {
     $accounts = Account::findAll([]);
     foreach ($accounts as $account) {
         $accountId = $account->_id;
         $setting = HelpDeskSetting::findOne(['accountId' => $accountId]);
         if (!empty($setting)) {
             $maxWaitTime = $setting->maxWaitTime;
             // Close timeout conversation
             $chatConversations = ChatConversation::findAll(['accountId' => $accountId, 'status' => ChatConversation::STATUS_OPEN, 'lastChatTime' => ['$lt' => TimeUtil::msTime(time() - $maxWaitTime * 60)]]);
             foreach ($chatConversations as $chatConversation) {
                 HelpDesk::disconnect($chatConversation->_id, ['type' => 'brake']);
             }
             // Delete timeout pending client
             $pendingClients = PendingClient::findAll(['accountId' => $accountId, 'lastPingTime' => ['$lt' => TimeUtil::msTime(time() - PendingClient::PING_THRESHOLD)]]);
             foreach ($pendingClients as $pendingClient) {
                 $pendingClient->delete();
             }
             // Clean offline helpdesk
             $cache = Yii::$app->cache;
             $onlineHelpDesks = $cache->get(HelpDesk::CACHE_PREFIX_HELPDESK_PING . $accountId);
             if (!empty($onlineHelpDesks)) {
                 foreach ($onlineHelpDesks as $deskId => $lastPingTime) {
                     if ($lastPingTime < TimeUtil::msTime(time() - HelpDesk::PING_THRESHOLD)) {
                         HelpDesk::leave($deskId, $accountId, ['type' => 'droping']);
                     }
                 }
             }
         }
     }
 }
 public function perform()
 {
     $args = $this->args;
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m', $datetime);
     $monthData = ModelStatsMemberDaily::getMonthData($dateStr);
     $rowsMonthly = [];
     foreach ($monthData as $item) {
         $origin = $item['_id']['origin'];
         $originName = $item['_id']['originName'];
         $accountId = $item['_id']['accountId'];
         $total = $item['total'];
         $statsMemberMonthly = ModelStatsMemberMonthly::getByDateAndOriginInfo($dateStr, $origin, $originName, $accountId);
         if (!empty($statsMemberMonthly)) {
             $statsMemberMonthly->total = $total;
             try {
                 $statsMemberMonthly->save(true, ['total']);
             } catch (Exception $e) {
                 ResqueUtil::log(['Update StatsMemberMonthly error' => $e->getMessage(), 'StatsMemberMonthly' => $statsMemberMonthly]);
                 continue;
             }
         } else {
             $rowsMonthly[] = ['month' => $dateStr, 'origin' => $origin, 'originName' => $originName, 'accountId' => $accountId, 'total' => $total];
         }
     }
     ModelStatsMemberMonthly::batchInsert($rowsMonthly);
     return true;
 }
 public function perform()
 {
     $args = $this->args;
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $accountId = $args['accountId'];
     return ModelStatsCampaignProductCodeQuarterly::generateByYearAndQuarter($accountId, $datetime);
 }
 /**
  * @args {"description": "Direct: Stats of coupon"}
  */
 public function perform()
 {
     $args = $this->args;
     //Get date from args or today
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     $stats = CouponLog::getStats($dateStr);
     if (!empty($stats)) {
         self::createStatsCouponLog($dateStr, $stats);
     }
     return true;
 }
 /**
  * @args {"description": "Delay: Stats of questionnaire answer"}
  */
 public function perform()
 {
     $args = $this->args;
     //Get date from args or today
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     //in case of too much data, get stats by questionnaire
     $skip = 0;
     $limit = 100;
     $query = Questionnaire::find()->orderBy(['_id' => SORT_ASC]);
     $query = $query->offset($skip)->limit($limit);
     $questionnaires = $query->all();
     while (!empty($questionnaires)) {
         $statsRows = [];
         foreach ($questionnaires as $questionnaire) {
             $stats = QuestionnaireLog::getAnswerStats($questionnaire->_id, $dateStr);
             //group stats by questionId
             $rows = [];
             foreach ($stats as $stat) {
                 $questionIdStr = (string) $stat['_id']['questionId'];
                 $optionValue = $stat['_id']['value'];
                 $rows[$questionIdStr][] = ['option' => $optionValue, 'count' => $stat['count']];
             }
             //format stats data, and save it
             foreach ($rows as $questionIdStr => $answerStats) {
                 $questionId = new MongoId($questionIdStr);
                 $statsAnswerDaily = ModelStatsQuestionnaireAnswerDaily::getByQuestionIdAndDate($questionId, $dateStr);
                 if (empty($statsAnswerDaily)) {
                     $statsRows[] = ['questionId' => $questionId, 'stats' => $answerStats, 'date' => $dateStr, 'accountId' => $questionnaire->accountId];
                 } else {
                     $statsAnswerDaily->stats = $answerStats;
                     try {
                         $statsAnswerDaily->save();
                     } catch (Exception $e) {
                         ResqueUtil::log(['Update StatsQuestionnaireAnswerDaily error' => $e->getMessage(), 'StatsQuestionnaireAnswerDaily' => $statsAnswerDaily]);
                         continue;
                     }
                 }
             }
         }
         ModelStatsQuestionnaireAnswerDaily::batchInsert($statsRows);
         $skip += $limit;
         $query = $query->offset($skip)->limit($limit);
         //free $questionnaires
         unset($questionnaires);
         $questionnaires = $query->all();
     }
     return true;
 }
 private function _transformMessages($result, $channelId)
 {
     $items = $item = [];
     if (!empty($result) && !empty($result['results']) && count($result['results']) > 0) {
         foreach ($result['results'] as $message) {
             $messages = $message['message'];
             if (!empty($messages)) {
                 $item = ['id' => empty($messages['messageId']) ? '' : $messages['messageId'], 'channelId' => $channelId, 'message' => !isset($messages['content']) ? '' : $messages['content'], 'msgType' => $messages['msgType'], 'keycode' => !isset($message['keycode']) ? '' : $message['keycode'], 'interactTime' => TimeUtil::msTime2String($messages['createTime'], 'Y-m-d H:i:s')];
                 $items[] = $item;
             }
         }
     }
     return $items;
 }
 /**
  * Login
  *
  * <b>Request Type</b>: POST<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/chat/site/login<br/><br/>
  * <b>Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for the help desk to login.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *     email: string, the user email, required<br/>
  *     password: string, the user password, required<br/>
  *     <br/><br/>
  *
  * <b>Response Params:</b><br/>
  *     ack: integer, mark the create result, 0 means create successfully, 1 means create fail<br/>
  *     msg: string, if create fail, it contains the error message<br/>
  *     data: array, json array to describe the users detail information<br/>
  *     <br/><br/>
  *
  * <b>Request Example:</b><br/>
  * <pre>
  * {
  *     "email"    : "*****@*****.**",
  *     "password" : "abc123"
  * }
  * </pre>
  * <br/><br/>
  *
  * <b>Response Example</b>:<br/>
  * <pre>
  * {
  *    'ack'  : 1,
  *    'data' : {
  *        "accessToken" : "7f2d1e92-9629-8429-00be-2d9c6d64acdb",
  *        "userInfo"    : {
  *            "name"   : "harry",
  *            "avatar" : "path/to/avatar"
  *        }
  *    }
  * }
  * </pre>
  */
 public function actionLogin()
 {
     $params = $this->getParams();
     $deviceToken = $this->getParams('deviceToken');
     $environment = $this->getParams('environment');
     if (empty($params['email']) || empty($params['password'])) {
         throw new BadRequestHttpException("parameters missing");
     }
     $helpdesk = HelpDesk::getByEmail($params['email']);
     if (empty($helpdesk)) {
         throw new ForbiddenHttpException("用戶不存在");
     }
     if (!$helpdesk->isActivated) {
         throw new ForbiddenHttpException("用戶未激活,请激活后使用");
     }
     if (!$helpdesk->isEnabled) {
         throw new ForbiddenHttpException("该账号已被禁用,请与管理员联系");
     }
     if ($helpdesk->validatePassword($params['password'])) {
         $tokens = Token::getUnexpiredByUserId($helpdesk->_id);
         if (!empty($tokens)) {
             $data = ['isForcedOffline' => true, 'id' => $helpdesk->_id . ''];
             $accountId = $tokens[0]->accountId;
             Yii::$app->tuisongbao->triggerEvent(ChatConversation::EVENT_FORCED_OFFLINE, $data, [ChatConversation::CHANNEL_GLOBAL . $accountId]);
             //deviceToken changed, push forcedOffline
             if (empty($deviceToken) && !empty($helpdesk->deviceToken) || !empty($deviceToken) && !empty($helpdesk->deviceToken) && $deviceToken != $helpdesk->deviceToken) {
                 $extra = ['deskId' => $helpdesk->_id . '', 'sentTime' => TimeUtil::msTime()];
                 ChatConversation::pushMessage($helpdesk->_id, ChatConversation::EVENT_FORCED_OFFLINE, $extra);
             }
             Token::updateAll(['$set' => ['expireTime' => new \MongoDate()]], ['_id' => ['$in' => Token::getIdList($tokens)]]);
         }
         $isFirstLogin = empty($helpdesk->lastLoginAt);
         $accessToken = Token::createByHelpDesk($helpdesk);
         if (isset($deviceToken)) {
             $helpdesk->loginDevice = HelpDesk::MOBILEAPP;
         } else {
             $helpdesk->loginDevice = HelpDesk::BROWSER;
         }
         $helpdesk->deviceToken = $deviceToken;
         $helpdesk->environment = $environment;
         $helpdesk->lastLoginAt = new \MongoDate();
         $helpdesk->save(true, ['deviceToken', 'loginDevice', 'environment', 'lastLoginAt']);
         $userInfo = ['badge' => $helpdesk->badge, 'name' => $helpdesk->name, 'email' => $helpdesk->email, 'language' => $helpdesk->language, 'avatar' => empty($helpdesk->avatar) ? '' : $helpdesk->avatar, 'id' => (string) $helpdesk->_id, 'accountId' => (string) $helpdesk['accountId'], 'notificationType' => $helpdesk->notificationType, 'isFirstLogin' => $isFirstLogin];
         return ["accessToken" => $accessToken['accessToken'], 'userInfo' => $userInfo];
     } else {
         throw new ForbiddenHttpException("密码错误");
     }
 }
 public function perform()
 {
     $args = $this->args;
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $accountId = $args['accountId'];
     //Assume that the subChannel is the secode element in properties
     $propertyKey = $args['properties'][1];
     $memberProperty = MemberProperty::findOne(['propertyId' => $propertyKey]);
     if ($memberProperty != null) {
         return ModelStatsMemberPropTradeCodeQuarterly::generateByYearAndQuarter((string) $memberProperty['_id'], $accountId, $datetime);
     } else {
         ResqueUtil::log("Fail to get memberProperty with propertyId {$propertyKey}");
     }
     return false;
 }
 /**
  * Provide card
  *
  * <b>Request Type</b>: POST<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/api/member/card/provide-card<br/><br/>
  * <b>Response Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for provide card.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *     cardId: string<br/>
  *     cardNumbers: Array, card number<br/>
  *     names: Array
  *     tags: Array<br/>
  *     cardExpiredAt: timestamp<br/>
  *     <br/><br/>
  *
  * <b>Response Params:</b><br/>
  *     message:
  *     <br/><br/>
  *
  * <br/><br/>
  *
  * <b>Response Example</b>:<br/>
  * <pre>
  *  {"message" : "OK"}
  * </pre>
  */
 public function actionProvideCard()
 {
     $params = $this->getParams();
     $accountId = $this->getAccountId();
     $params['accountId'] = $accountId . '';
     if (empty($params['cardId'])) {
         throw new BadRequestHttpException('param error');
     }
     if (empty($params['cardExpiredAt'])) {
         throw new InvalidParameterException(['schedule-picker' => \Yii::t('common', 'required_filed')]);
     }
     $cardId = new \MongoId($params['cardId']);
     $card = MemberShipCard::findByPk($cardId);
     if (empty($card)) {
         throw new BadRequestHttpException(\Yii::t('member', 'no_card_find'));
     }
     if ($card->isAutoUpgrade) {
         throw new InvalidParameterException(Yii::t('member', 'error_issue_auto_card'));
     }
     if ($params['cardExpiredAt'] < TimeUtil::msTime()) {
         throw new InvalidParameterException(['schedule-picker' => \Yii::t('member', 'not_less_than_current')]);
     }
     $members = [];
     if (!empty($params['cardNumbers']) && is_array($params['cardNumbers'])) {
         $members = Member::getByCardNumbers($params['cardNumbers']);
         if (empty($members)) {
             throw new InvalidParameterException(['cardNumber' => \Yii::t('member', 'no_member_find')]);
         }
     } else {
         if (!empty($params['names']) && is_array($params['names'])) {
             $members = Member::getByNames($params['names']);
             if (empty($members)) {
                 throw new InvalidParameterException(['memberNames' => \Yii::t('member', 'no_member_find')]);
             }
         } else {
             if (!empty($params['tags']) && is_array($params['tags'])) {
                 $members = Member::getByTags($params['tags']);
                 if (empty($members)) {
                     throw new InvalidParameterException(['memberTags' => \Yii::t('member', 'no_member_find')]);
                 }
             }
         }
     }
     $memberIds = Member::getIdList($members);
     Member::updateAll(['$set' => ['cardId' => $cardId, 'cardExpiredAt' => $params['cardExpiredAt']]], ['_id' => ['$in' => $memberIds]]);
     return ['message' => 'OK'];
 }
Beispiel #13
0
 /**
  * @args {"description": "Direct: Analysis daily promotion code "}
  */
 public function perform()
 {
     $yesterday = ModelPromotionCodeAnalysis::getTime(-1);
     $type = new MongoInt32(ModelPromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_TOTAL);
     $where = ['createdAt' => $yesterday, 'type' => $type];
     $status = ModelPromotionCodeAnalysis::checkExistData($where);
     if ($status) {
         $yesterdayStamp = TimeUtil::today() - 24 * 3600;
         $yesterday = new MongoDate($yesterdayStamp);
         //get campaignlogs in yesterday
         $campaignLogs = ModelPromotionCodeAnalysis::getMemberCampaignLog();
         //create datas
         if (!empty($campaignLogs)) {
             $campaignData = [];
             foreach ($campaignLogs as $key => $campaignLog) {
                 //get total the day before yesterday
                 $beforeYesterday = new MongoDate(TimeUtil::today() - 2 * 24 * 3600);
                 $productId = $campaignLog['_id']['productId'];
                 $campaignId = $campaignLog['_id']['campaignId'];
                 $accountId = $campaignLog['_id']['accountId'];
                 $condition = ['productId' => $productId, 'campaignId' => $campaignId, 'accountId' => $accountId, 'createdAt' => $beforeYesterday, 'type' => $type];
                 $beforeYesterdayData = ModelPromotionCodeAnalysis::findOne($condition);
                 if (empty($beforeYesterdayData)) {
                     $beforeYesterdayData['total'] = 0;
                 }
                 $condition = ['campaignId' => $campaignId, 'accountId' => $accountId, 'productId' => $productId];
                 $number = ModelPromotionCodeAnalysis::checkMemberUnique($condition, TimeUtil::today());
                 //subtract the member who is recorded before
                 $total = $beforeYesterdayData['total'] + $number;
                 $campaignLogs[$key]['total'] = $total;
             }
             $campaignData = ModelPromotionCodeAnalysis::createAnalysisData($campaignLogs, $type, $yesterday);
             if (false === ModelPromotionCodeAnalysis::batchInsert($campaignData)) {
                 LogUtil::error(['message' => 'Faild to create daily data', 'date' => date('Y-m-d H:i:s'), 'data' => json_encode($campaignData)], 'resque');
             }
         }
         //set the default value when the value is not exists
         $yesterdayStamp -= 3600 * 24;
         ModelPromotionCodeAnalysis::setDefault($yesterdayStamp, $type);
     } else {
         LogUtil::info(['message' => 'Total analysis data is exists', 'date' => date('Y-m-d H:i:s')], 'resque');
     }
     return true;
 }
 private static function _setStatsMemberPropTradeQuarterly($startTime, $endTime, $args)
 {
     //Assume that the subChannel is the secode element in properties
     $propertyKey = $args['properties'][1];
     $memberProperty = MemberProperty::findOne(['propertyId' => $propertyKey]);
     if (!empty($memberProperty)) {
         $startQuarter = TimeUtil::getQuarter($startTime);
         $endQuarter = TimeUtil::getQuarter($endTime);
         for ($quarter = $startQuarter; $quarter <= $endQuarter; ++$quarter) {
             $year = date('Y', $startTime);
             $condition = ['accountId' => $args['accountId'], 'year' => $year, 'quarter' => $quarter];
             StatsMemberPropTradeQuarterly::deleteAll($condition);
             self::generateStatsMemberPropTradeQuarterlyData((string) $memberProperty['_id'], $condition);
             LogUtil::info(['message' => $quarter . ' :Run StatsMemberPropTradeQuarterly'], 'update_job');
         }
     } else {
         LogUtil::info(['message' => 'Can not find this propertyId:' . $propertyKey], 'update_job');
     }
 }
 public function perform()
 {
     //accountId, properties are required fileds
     $args = $this->args;
     if (empty($args['accountId']) || empty($args['properties'])) {
         ResqueUtil::log('Missing required arguments accountId or properties!');
         return false;
     }
     $date = empty($args['date']) ? '' : $args['date'];
     $datetime = TimeUtil::getDatetime($date);
     $dateStr = date('Y-m-d', $datetime);
     $start = new MongoDate($datetime);
     $end = new MongoDate(strtotime('+1 day', $datetime));
     $accountId = new MongoId($args['accountId']);
     $condition = ['accountId' => $accountId, 'createdAt' => ['$gte' => $start, '$lt' => $end]];
     $campaignLogs = self::getCampaignLog($condition);
     if (empty($campaignLogs)) {
         LogUtil::info(['date' => date('Y-m-d H:i:s'), 'message' => $dateStr . ': campaignLogs is empty,no need to store data'], 'resque');
         return true;
     }
     //get all member info
     $memberInfos = self::getMemberInfo($condition);
     //Get all the property mongo id for comparison
     $condition = ['propertyId' => ['$in' => $args['properties']], 'accountId' => $accountId];
     $propertyIdStrs = self::getPropertyIds($condition);
     //Generate the meta data for inserting
     $statsRows = [];
     foreach ($campaignLogs as $campaignLog) {
         $campaignLog = $campaignLog['_id'];
         $redeemTime = self::getRedeemTime($campaignLog);
         //check the redeem time whether exists
         $condition = ['code' => $campaignLog['code'], 'productId' => $campaignLog['productId'], 'month' => date('Y-m', $redeemTime)];
         $memberCampaignLogDaily = ModelStatsMemberCampaignLogDaily::findOne($condition);
         if (empty($memberCampaignLogDaily)) {
             $memProperty = self::getProperty((string) $campaignLog['member']['id'], $memberInfos, $propertyIdStrs);
             $statsRows[] = ['memberId' => $campaignLog['member']['id'], 'memProperty' => $memProperty, 'productId' => $campaignLog['productId'], 'code' => $campaignLog['code'], 'year' => date('Y', $redeemTime), 'month' => date('Y-m', $redeemTime), 'quarter' => TimeUtil::getQuarter($redeemTime), 'accountId' => $accountId, 'createdAt' => new MongoDate(strtotime('+1 day', $datetime) - 1)];
         }
     }
     ModelStatsMemberCampaignLogDaily::batchInsert($statsRows);
     unset($statsRows, $memberCampaignLogDaily, $condition, $memProperty, $memberInfos);
     return true;
 }
 /**
  * @args {"description": "Direct: Analysis participate promotion code "}
  */
 public function perform()
 {
     $yesterday = ModelPromotionCodeAnalysis::getTime(-1);
     $type = new MongoInt32(ModelPromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_PARTICIPATE);
     $where = ['createdAt' => $yesterday, 'type' => $type];
     $status = ModelPromotionCodeAnalysis::checkExistData($where);
     if ($status) {
         $yesterdayStamp = TimeUtil::today() - 24 * 3600;
         $yesterday = new MongoDate($yesterdayStamp);
         $createWhere = ModelPromotionCodeAnalysis::getCreateTime();
         $campaignIds = CampaignLog::distinct('campaignId', $createWhere);
         $campaignLogs = [];
         if (!empty($campaignIds)) {
             $where = array_merge($createWhere, ['campaignId' => ['$in' => $campaignIds]]);
             $campaignLogs = CampaignLog::getCollection()->aggregate([['$match' => $where], ['$group' => ['_id' => ['campaignId' => '$campaignId', 'memberId' => '$member.id', 'accountId' => '$accountId', 'productId' => '$productId']]]]);
         }
         if (!empty($campaignLogs)) {
             //get total for take part in a campaign
             $campaignData = [];
             foreach ($campaignLogs as $data) {
                 $campaignId = $data['_id']['campaignId'];
                 $key = (string) $campaignId . (string) $data['_id']['productId'];
                 if (isset($campaignData[$key])) {
                     //to sum the total in every product in same campaign
                     $campaignData[$key]['total'] += 1;
                 } else {
                     $product = Product::findByPk($data['_id']['productId']);
                     $productName = empty($product['name']) ? '' : $product['name'];
                     $result = ['productId' => $data['_id']['productId'], 'productName' => $productName, 'campaignId' => $campaignId, 'accountId' => $data['_id']['accountId'], 'createdAt' => $yesterday, 'total' => 1, 'type' => $type];
                     $campaignData[$key] = $result;
                 }
             }
             if (false === ModelPromotionCodeAnalysis::batchInsert($campaignData)) {
                 LogUtil::error(['message' => 'Faild to create daily data', 'date' => date('Y-m-d H:i:s'), 'data' => json_encode($campaignData)], 'resque');
             }
             unset($datas, $campaignIds, $campaignData);
         }
     } else {
         LogUtil::info(['message' => 'Participate analysis data is exists', 'date' => date('Y-m-d H:i:s')], 'resque');
     }
     return true;
 }
 /**
  * @args {"description": "Direct: Analysis total participate"}
  */
 public function perform()
 {
     $yesterday = ModelPromotionCodeAnalysis::getTime(-1);
     $type = new MongoInt32(ModelPromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_TOTAL_PARTICIPATE);
     $where = ['createdAt' => $yesterday, 'type' => $type];
     $status = ModelPromotionCodeAnalysis::checkExistData($where);
     if ($status) {
         $yesterdayStamp = TimeUtil::today() - 24 * 3600;
         $yesterday = new MongoDate($yesterdayStamp);
         $where = ModelPromotionCodeAnalysis::getCreateTime();
         $campaignData = ModelPromotionCodeAnalysis::getMemberAllTimes($where);
         $campaignData = ModelPromotionCodeAnalysis::createAnalysisData($campaignData, $type, $yesterday);
         if (false === ModelPromotionCodeAnalysis::batchInsert($campaignData)) {
             LogUtil::error(['message' => 'Faild to create daily data', 'date' => date('Y-m-d H:i:s'), 'data' => json_encode($campaignData)], 'resque');
         }
     } else {
         LogUtil::info(['message' => 'Total participate analysis data is exists', 'date' => date('Y-m-d H:i:s')], 'resque');
     }
     return true;
 }
 public function perform()
 {
     $args = $this->args;
     if (empty($args['accountId']) || empty($args['properties'][0])) {
         ResqueUtil::log('Missing required arguments accountId or properties!');
         return false;
     }
     $accountId = new MongoId($args['accountId']);
     $property = $args['properties'][0];
     $memberProperty = MemberProperty::getByPropertyId($accountId, $property);
     if (empty($memberProperty)) {
         ResqueUtil::log('Can not find member property with propertyId:' . $property);
         return false;
     }
     $date = empty($args['date']) ? '' : $args['date'];
     $date = TimeUtil::getDatetime($date);
     $year = date('Y', $date);
     $quarter = TimeUtil::getQuarter($date);
     self::generateData($memberProperty, $property, $year, $quarter, $accountId);
     return true;
 }
 public function actionStatsMenusHits()
 {
     $openId = $this->getQuery('openId');
     $channelId = $this->getQuery('channelId');
     $count = 0;
     $lastTime = '';
     $results = [];
     if (empty($openId) || empty($channelId)) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $resultItem = Yii::$app->weConnect->statsMenusHits($openId, $channelId);
     if (!empty($resultItem)) {
         if (!empty($resultItem['profiles']) && !empty($resultItem['profiles']['menus']) && count($resultItem['profiles']['menus']) > 0) {
             $raw = $resultItem['profiles']['menus'];
             $count = !isset($raw['hitCount']) ? 0 : $raw['hitCount'];
             $lastTime = empty($raw['lastHitTime']) ? '' : TimeUtil::msTime2String($raw['lastHitTime'], 'Y-m-d H:i:s');
         }
     }
     $item = ['hitCount' => $count, 'lastHitTime' => $lastTime];
     return $item;
 }
 public function actionStatsCoupon()
 {
     $params = $this->getQuery();
     if (empty($params['id']) || !isset($params['startTime']) || !isset($params['endTime'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $id = new MongoId($params['id']);
     $couponLog = Coupon::findOne(["_id" => $id]);
     if (empty($couponLog)) {
         throw new BadRequestHttpException(Yii::t('product', 'membershipDiscount_is_deleted'));
     }
     //turn unix timestamp to string
     $startTime = TimeUtil::msTime2String($params['startTime'], 'Y-m-d');
     $endTime = TimeUtil::msTime2String($params['endTime'], 'Y-m-d');
     $couponPeriodInfo = StatsCouponLogDaily::getCouponLogStats($id, $startTime, $endTime);
     ArrayHelper::multisort($couponPeriodInfo, 'date', SORT_ASC);
     $dateCouPonStats = ArrayHelper::index($couponPeriodInfo, 'date');
     $item = $redeemedNum = $recievedNum = $date = [];
     $startDate = strtotime($startTime);
     $endDate = strtotime($endTime);
     if (!empty($couponPeriodInfo) && count($couponPeriodInfo) > 0) {
         while ($startDate <= $endDate) {
             $dateStr = date('Y-m-d', $startDate);
             if (!empty($dateCouPonStats[$dateStr])) {
                 $date[] = $dateStr;
                 $recievedNum[] = $dateCouPonStats[$dateStr]['recievedNum'];
                 $redeemedNum[] = $dateCouPonStats[$dateStr]['redeemedNum'];
             } else {
                 $date[] = $dateStr;
                 $recievedNum[] = 0;
                 $redeemedNum[] = 0;
             }
             $startDate = strtotime($dateStr . ' +1 day');
         }
     }
     $item = ['date' => $date, 'count' => ['recievedNum' => $recievedNum, 'redeemedNum' => $redeemedNum]];
     return $item;
 }
 public function perform()
 {
     $args = $this->args;
     if (empty($args['accountId']) || empty($args['properties'][0])) {
         ResqueUtil::log('Missing required arguments accountId or properties!');
         return false;
     }
     $accountId = new \MongoId($args['accountId']);
     $property = $args['properties'][0];
     $memberProperty = MemberProperty::findOne(['propertyId' => $property, 'accountId' => $accountId]);
     if (empty($memberProperty)) {
         ResqueUtil::log('Can not find member property with propertyId:' . $property);
         return false;
     }
     $date = empty($args['date']) ? '' : $args['date'];
     $date = TimeUtil::getDatetime($date);
     $month = date('Y-m', $date);
     $startDate = strtotime($month);
     $endDate = strtotime(date('Y-m', strtotime('+1 month', $date)));
     $raw = Member::getCollection()->aggregate([['$unwind' => '$properties'], ['$match' => ['createdAt' => ['$gte' => new \MongoDate($startDate), '$lt' => new \MongoDate($endDate)], 'properties.id' => $memberProperty->_id, 'accountId' => $accountId]], ['$group' => ['_id' => '$properties.value', 'total' => ['$sum' => 1]]]]);
     foreach ($raw as $item) {
         $total = $item['total'];
         $propValue = $item['_id'];
         // save the stats member property monthly
         $statsMemberPropMonthly = ModelStatsMemberPropMonthly::findOne(['propId' => $property, 'propValue' => $propValue, 'month' => $month, 'accountId' => $accountId]);
         if (empty($statsMemberPropMonthly)) {
             $statsMemberPropMonthly = new ModelStatsMemberPropMonthly();
             $statsMemberPropMonthly->propId = $property;
             $statsMemberPropMonthly->propValue = $propValue;
             $statsMemberPropMonthly->month = $month;
             $statsMemberPropMonthly->accountId = $accountId;
         }
         $statsMemberPropMonthly->total = $total;
         ResqueUtil::log($statsMemberPropMonthly->attributes);
         $statsMemberPropMonthly->save();
     }
     return true;
 }
 /**
  * Get question option answer's stats info
  * @throws BadRequestHttpException
  * @return array, [{"option": "Yes", "count": 12}]
  */
 public function actionAnswers()
 {
     $params = $this->getQuery();
     if (empty($params['questionId'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $question = Question::findByPk(new MongoId($params['questionId']));
     if (empty($question) || $question->type === Question::TYPE_INPUT) {
         throw new InvalidParameterException(Yii::t('content', 'invalid_question'));
     }
     //turn unix timestamp to string
     $startDateStr = isset($params['startTime']) ? TimeUtil::msTime2String($params['startTime'], 'Y-m-d') : null;
     $endDateStr = isset($params['endTime']) ? TimeUtil::msTime2String($params['endTime'], 'Y-m-d') : null;
     $stats = StatsQuestionnaireAnswerDaily::getQuestionOptionStats(new MongoId($params['questionId']), $startDateStr, $endDateStr);
     $statsMap = ArrayHelper::map($stats, 'option', 'count');
     $options = [];
     $count = [];
     foreach ($question->options as $option) {
         $options[] = $option['content'];
         $count[] = empty($statsMap[$option['content']]) ? 0 : $statsMap[$option['content']];
     }
     return ['options' => $options, 'count' => $count];
 }
 public function actionUpdate($id)
 {
     $campaign = Campaign::findByPk($id);
     if (empty($campaign)) {
         throw new BadRequestHttpException(Yii::t('product', 'campaign_not_found'));
     }
     if (MongodbUtil::isExpired($campaign->endTime)) {
         throw new BadRequestHttpException(Yii::t('product', 'can_not_update'));
     }
     $params = $this->getParams();
     $params['startTime'] = empty($params['startTime']) ? $campaign->startTime : new \MongoDate(TimeUtil::ms2sTime($params['startTime']));
     $params['endTime'] = empty($params['endTime']) ? $campaign->endTime : new \MongoDate(TimeUtil::ms2sTime($params['endTime']));
     $attributeNames = null;
     foreach ($params as $key => $value) {
         if (in_array($key, ['productIds', 'gift', 'products', 'tags', 'channels'])) {
             $attributeNames[] = 'promotion';
             $promotion = $campaign->promotion;
             $promotion['type'] = Campaign::TYPE_PROMOTION_CODE;
             $key == 'productIds' ? $promotion['data'] = $params['productIds'] : '';
             $key == 'gift' ? $promotion['gift'] = $params['gift'] : '';
             $key == 'products' ? $promotion['products'] = $params['products'] : '';
             $key == 'tags' ? $promotion['tags'] = $params['tags'] : '';
             $key == 'channels' ? $promotion['channels'] = $params['channels'] : '';
             $campaign->promotion = $promotion;
         } else {
             if (in_array($key, ['participantCount', 'limitTimes'])) {
                 $attributeNames[] = $key;
                 $campaign->{$key} = is_null($value) ? null : intval($value);
             } else {
                 $attributeNames[] = $key;
                 $campaign->{$key} = $value;
             }
         }
     }
     $campaign->save(true, $attributeNames);
     return $campaign;
 }
 public function actionStatistics()
 {
     $startTime = $this->getQuery('startTime');
     $endTime = $this->getQuery('endTime');
     $accountId = $this->getAccountId();
     $condition = ['accountId' => $accountId, 'isDeleted' => BaseModel::NOT_DELETED];
     if (!empty($startTime) && !empty($endTime)) {
         $condition['createdAt'] = ['$gt' => new \MongoDate(TimeUtil::ms2sTime($startTime)), '$lt' => new \MongoDate(TimeUtil::ms2sTime($endTime))];
     }
     //get the original statistics from db.(raw data)
     $clientCount = ChatConversation::getClientCount($condition);
     $conversationCount = ChatConversation::count($condition);
     $clientMessageCount = ChatMessage::countClientMessage($condition);
     $conversationDailyStatistics = ChatConversation::getDailyData($condition);
     $messageDailyStatistics = ChatMessage::getDailyData($condition);
     //format the statistics for chart
     $categories = [];
     $messageCountSeries = [];
     $clientCountSeries = [];
     $conversationCountSeries = [];
     foreach ($conversationDailyStatistics as $conversationDay) {
         foreach ($messageDailyStatistics as $messageDay) {
             if ($conversationDay['date'] == $messageDay['date']) {
                 $conversationDay['messageCount'] = $messageDay['messageCount'];
             }
         }
         if (empty($conversationDay['messageCount'])) {
             $conversationDay['messageCount'] = 0;
         }
         $categories[] = $conversationDay['date'];
         $messageCountSeries[] = $conversationDay['messageCount'];
         $clientCountSeries[] = $conversationDay['clientCount'];
         $conversationCountSeries[] = $conversationDay['conversationCount'];
     }
     $statistics = ['categories' => $categories, 'series' => [['name' => 'helpdesk_users_count', 'data' => $clientCountSeries], ['name' => 'helpdesk_sessions_count', 'data' => $conversationCountSeries], ['name' => 'helpdesk_sent_message_count', 'data' => $messageCountSeries]]];
     return ['clientCount' => $clientCount, 'conversationCount' => $conversationCount, 'clientMessageCount' => $clientMessageCount, 'statistics' => $statistics];
 }
 public function actionUpdate($id)
 {
     $params = $this->getParams();
     if (empty($params['status']) || !isset($params['price'])) {
         throw new BadRequestHttpException(Yii::t('common', 'parameters_missing'));
     }
     $storeGoods = StoreGoods::findByPk(new \MongoId($id));
     if (empty($storeGoods)) {
         throw new InvalidParameterException(Yii::t('store', 'invalid_goods_id'));
     }
     $storeGoods->pictures = empty($params['pictures']) ? $storeGoods->pictures : $params['pictures'];
     $price = floatval($params['price']);
     if ($price <= 0) {
         throw new InvalidParameterException(Yii::t('store', 'price_error'));
     }
     $storeGoods->price = $price;
     if ($params['status'] == StoreGoods::STATUS_ON) {
         $storeGoods->status = StoreGoods::STATUS_ON;
         $storeGoods->onSaleTime = new \MongoDate();
     } else {
         if ($params['status'] == StoreGoods::STATUS_OFF && isset($params['onSaleTime']) && $params['onSaleTime'] !== '') {
             if (time() > TimeUtil::ms2sTime($params['onSaleTime'])) {
                 throw new InvalidParameterException(['onSaleTime' => \Yii::t('product', 'not_less_than_current')]);
             } else {
                 $storeGoods->status = StoreGoods::STATUS_OFF;
                 $storeGoods->onSaleTime = new \MongoDate(TimeUtil::ms2sTime($params['onSaleTime']));
             }
         } else {
             if ($params['status'] == StoreGoods::STATUS_OFF && (!isset($params['onSaleTime']) || $params['onSaleTime'] === '')) {
                 $storeGoods->status = StoreGoods::STATUS_OFF;
                 $storeGoods->onSaleTime = null;
                 $storeGoods->offShelfTime = new \MongoDate();
             } else {
                 throw new BadRequestHttpException(Yii::t('common', 'data_error'));
             }
         }
     }
     if ($storeGoods->save(true)) {
         $storeGoods->_id = (string) $storeGoods->_id;
         return $storeGoods;
     } else {
         throw new ServerErrorHttpException(Yii::t('common', 'save_fail'));
     }
 }
Beispiel #26
0
 public function conver2MongoDate($attribute)
 {
     if ($attribute == 'startTime' || $attribute == 'endTime') {
         $time = $this->{$attribute};
         if (!empty($time) && is_numeric($time)) {
             $this->{$attribute} = new MongoDate(TimeUtil::ms2sTime($time));
         }
     } else {
         return true;
     }
 }
 /**
  * Send Mass message
  *
  * <b>Request Type</b>: POST<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/api/channel/mass-messages<br/><br/>
  * <b>Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for sending mass message.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *     channelId: string<br/>
  *     scheduleTime: long, the scheduled time, or empty which means to send right now<br/>
  *     userQuery.tags: array<br/>
  *     userQuery.gender: male, female or empty<br/>
  *     userQuery.country: string<br/>
  *     userQuery.province: string<br/>
  *     userQuery.city: string<br/>
  *     msgType: TEXT or MPNEWS<br/>
  *     content: string, if TEXT<br/>
  *     content.articles, if MPNEWS<br/>
  *     mixed: bool<br/>
  *     <br/><br/>
  *
  * <b>Response Params:</b><br/>
  *     msg: string, if query fail, it contains the error message<br/>
  *     <br/><br/>
  *
  * <br/><br/>
  *
  * <b>Response Example</b>:<br/>
  * <pre>
  * {
  *   "message": "OK"
  * }
  * </pre>
  */
 public function actionCreate()
 {
     $massmessage = $this->getParams();
     $channelId = $this->getChannelId();
     if (!empty($massmessage['scheduleTime']) && $massmessage['scheduleTime'] < TimeUtil::msTime()) {
         throw new InvalidParameterException(['schedule-picker' => Yii::t('channel', 'schedule_time_error')]);
     }
     unset($massmessage['channelId']);
     $result = Yii::$app->weConnect->createMassMessage($channelId, $massmessage);
     if ($result) {
         return ['message' => 'OK'];
     } else {
         throw new ServerErrorHttpException('Create mass message fail.');
     }
 }
Beispiel #28
0
 public function validateTime($attribute)
 {
     $time = $this->{$attribute};
     $time = TimeUtil::ms2sTime($time);
     $this->{$attribute} = new \MongoDate($time);
     if ($attribute == 'startTime') {
         $now = time();
         if ($time < $now) {
             throw new InvalidParameterException(['beginDatePicker' => \Yii::t('product', 'invalid_start_time')]);
         }
     } else {
         if ($attribute == 'endTime') {
             if ($time <= MongodbUtil::MongoDate2TimeStamp($this->startTime)) {
                 throw new InvalidParameterException(['endDatePicker' => \Yii::t('product', 'invalid_end_time')]);
             }
         }
     }
 }
 /**
  * Check bind.
  *
  * <b>Request Type</b>: GET<br/><br/>
  * <b>Request Endpoint</b>:http://{server-domain}/api/mobile/check-bind<br/><br/>
  * <b>Response Content-type</b>: application/json<br/><br/>
  * <b>Summary</b>: This api is used for check bind.
  * <br/><br/>
  *
  * <b>Request Params</b>:<br/>
  *     <br/><br/>
  *
  * <b>Response Params:</b><br/>
  *     redirect<br/>
  *     <br/><br/>
  *
  * <br/><br/>
  *
  * <b>Response Example</b>:<br/>
  * <pre>
  *  redirect('http://dev.cp.augmarketing.cn/mobile/center?openId=3DoTAN2jmRmInqhC_CDLN7aSTzvfzo') or
  *  redirect('http://dev.cp.augmarketing.cn/mobile/center?memberId=549a73c3e9c2fb8d7c8b4569')
  * </pre>
  */
 public function actionCheckBind($type = '', $param = '')
 {
     $params = $this->getQuery();
     if (empty($params['state'])) {
         throw new BadRequestHttpException('missing params state');
     }
     $channelId = $params['state'];
     $channelInfo = Yii::$app->weConnect->getAccounts($channelId);
     if (empty($channelInfo[0]['channel'])) {
         throw new BadRequestHttpException('invalid channelId');
     }
     $userChannel = $channelInfo[0]['channel'];
     $redirect = !empty($type) ? base64_decode($param) : '';
     $mainDomain = Yii::$app->request->hostInfo;
     if ($userChannel == Account::WECONNECT_CHANNEL_ALIPAY) {
         if (empty($params['auth_code'])) {
             throw new BadRequestHttpException('missing param auth_code');
         }
         LogUtil::info(['params' => $params, 'channelId' => $channelId, 'message' => 'alipay info'], 'channel');
         if ($params['scope'] == 'auth_userinfo') {
             $alipayUserInfo = Yii::$app->weConnect->getAlipayUserInfo($channelId, $params['auth_code']);
             $openId = $alipayUserInfo['originId'];
         } else {
             //call weconnect to get openId
             $openId = Yii::$app->weConnect->getAlipayOpenId($channelId, $params['auth_code']);
         }
     } else {
         if (empty($params['openId'])) {
             $openIdInfo = $this->getOriginAndOpenId($params);
             $origin = $openIdInfo['origin'];
             $openId = $openIdInfo['openId'];
         } else {
             $origin = Member::WECHAT;
             $openId = $params['openId'];
         }
     }
     //get member unionId from weconnect
     try {
         if (empty($alipayUserInfo)) {
             //to suport alipay,because alipay did not get followers again
             $follower = Yii::$app->weConnect->getFollowerByOriginId($openId, $channelId);
         } else {
             $follower = $alipayUserInfo;
         }
     } catch (ApiDataException $e) {
         LogUtil::info(['WeConnect Exception' => 'Get follower info error', 'exception' => $e], 'channel');
         $follower = null;
     }
     //if follower not subscribed and (follower must subscribe before redirect or origin is weibo), redirect
     if ((empty($follower) || isset($follower['subscribed']) && $follower['subscribed'] != true) && ($this->mustSubscribe($redirect) || $origin === Member::WEIBO)) {
         return $this->redirect($this->getSubscribePage($origin, $channelId, $type, $redirect));
     }
     //if the channel is alipay,we need to judge the member info whether exists,if the info is empty,wo call the first url
     if ($userChannel == Account::WECONNECT_CHANNEL_ALIPAY) {
         if (isset($follower['authorized']) && $follower['authorized'] == false) {
             if ($params['scope'] == 'auth_userinfo') {
                 LogUtil::info(['message' => 'weConnect authorized fail', 'follower' => $follower], 'channel');
             } else {
                 $redirectUrl = $mainDomain . '/api/mobile/check-bind';
                 if (!empty($type) && !empty($param)) {
                     $redirectUrl .= "/{$type}/{$param}";
                 }
                 $redirectUrl .= '?state=' . $channelId . '&appId=' . $params['appId'];
                 $redirectUrl = urlencode($redirectUrl);
                 $url = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?" . "app_id=" . $params['appId'] . "&auth_skip=false&scope=auth_userinfo&redirect_uri={$redirectUrl}";
                 LogUtil::info(['message' => 'can not get detailed follower info', 'url' => $url, 'follower' => $follower], 'channel');
                 return $this->redirect($url);
             }
         } else {
             LogUtil::info(['message' => 'authorized', 'follower' => $follower], 'channel');
         }
     }
     if (!empty($follower['unionId'])) {
         //unionId exists
         $unionId = $follower['unionId'];
         $member = Member::getByUnionid($unionId);
         if (empty($member)) {
             //no unionId but openId
             $member = Member::getByOpenId($openId);
             if (!empty($member)) {
                 $member->unionId = $unionId;
                 $member->save(true, ['unionId']);
             }
         }
     } else {
         if (!empty($follower['originId'])) {
             $unionId = '';
             $member = Member::getByOpenId($openId);
         } else {
             if (empty($follower) && !empty($params['appid']) && $userChannel == Account::WECONNECT_CHANNEL_WEIXIN) {
                 LogUtil::info(['message' => 'Failed to get follower info', 'follower' => $follower, 'params' => $params]);
                 $appId = $params['appid'];
                 // not a follower, oAuth2.0 to get user_info
                 $member = Member::getByOpenId($openId);
                 if (empty($member)) {
                     $component = Yii::$app->weConnect->getComponentToken();
                     $componentAppId = $component['componentAppId'];
                     $state = $channelId;
                     $redirectUrl = Yii::$app->request->hostInfo . '/api/mobile/user-info';
                     if (!empty($redirect)) {
                         $redirectUrl = $redirectUrl . '/' . $type . '/' . $param;
                     }
                     LogUtil::info(['message' => 'oauth2 user_info redirecturl', 'url' => $redirectUrl]);
                     $redirectUrl = urlencode($redirectUrl);
                     $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appId}&redirect_uri={$redirectUrl}&response_type=code&scope=snsapi_userinfo&state={$state}&component_appid={$componentAppId}#wechat_redirect";
                     return $this->redirect($url);
                 } else {
                     //member exists, will redirect to member center or 403
                 }
             } else {
                 LogUtil::error(['Mobile member' => 'Failed to get follower info']);
                 return $this->redirect('/mobile/common/403');
             }
         }
     }
     LogUtil::info(['message' => 'Bind with follower', 'follower' => $follower], 'channel');
     if (empty($member)) {
         //if not exist redirect, get unionId to bind
         //urlencode to avoid lose $redirect query string when frontend get $redirect
         $redirect = urlencode($redirect);
         $redirectUrl = $mainDomain . '/mobile/member';
         if ($type == self::TYPE_REDIRECT) {
             $redirectUrl .= '/activate';
         } else {
             $redirectUrl .= '/center';
         }
         $redirectUrl .= "?openId={$openId}&channelId={$channelId}&unionId={$unionId}&redirect={$redirect}&redirectType={$type}";
     } else {
         //if member is disabled, redirect to 403
         if ($member->isDisabled) {
             return $this->redirect('/mobile/common/403');
         }
         //if exist redirect to member center
         $social = ['channel' => $channelId, 'openId' => $openId, 'origin' => $origin, 'originScene' => empty($follower['firstSubscribeSource']) ? '' : $follower['firstSubscribeSource']];
         $this->addNewSocial($member, $social);
         $memberId = $member['_id'] . '';
         if ($type == self::TYPE_REDIRECT) {
             $str = strpos($redirect, '?') !== false ? '&' : '?';
             $redirectUrl = $redirect . $str . "quncrm_member={$memberId}";
         } else {
             $accountId = new \MongoId($member['accountId']);
             $token = Token::createForMobile($accountId);
             if (empty($token['accessToken'])) {
                 throw new ServerErrorHttpException('Failed to create token for unknown reason.');
             }
             $accessToken = $token['accessToken'];
             $this->setAccessToken($accessToken);
             if ($type == self::TYPE_REDIRECT_INSIDE) {
                 $str = strpos($redirect, '?') !== false ? '&' : '?';
                 $redirectUrl = $redirect . $str . "memberId={$memberId}&channelId={$channelId}";
             } else {
                 $redirectUrl = $mainDomain . "/mobile/member/center?memberId={$memberId}&channelId={$channelId}";
                 if (!empty($member->cardExpiredAt) && $member->cardExpiredAt < TimeUtil::msTime()) {
                     $redirectUrl = $redirectUrl . '&cardExpired=1';
                 } else {
                     $redirectUrl = $redirectUrl . '&cardExpired=0';
                 }
             }
         }
     }
     return $this->redirect($redirectUrl);
 }
Beispiel #30
0
 public static function refund($accountId, $refundInfo)
 {
     $refund = new self();
     $refundNumber = StringUtil::getUniqueCode('refund', 'T');
     $refund->transactionId = empty($refundInfo['transactionId']) ? '' : $refundInfo['transactionId'];
     $refund->refundNumber = $refundNumber;
     $refund->accountId = $accountId;
     $refund->orderNumber = $refundInfo['orderNumber'];
     $refund->expectedAmount = $refundInfo['expectedAmount'];
     $refund->realAmount = $refundInfo['realAmount'];
     $refund->admin = $refundInfo['admin'];
     $refund->user = $refundInfo['user'];
     $refund->refundMode = $refundInfo['refundMode'];
     $refund->refundAt = empty($refundInfo['refundAt']) ? new MongoDate() : new MongoDate(TimeUtil::ms2sTime($refundInfo['refundAt']));
     $comments = empty($refundInfo['comments']) ? '' : $refundInfo['comments'];
     $refund->comments = $comments;
     $refund->subject = $refundInfo['subject'];
     return $refund->Save();
 }