private function processProductInfoData($header, $filePath, $classFunction, $params = []) { LogUtil::info(['message' => 'Begin to read csv file', 'fileName' => $filePath], 'resque'); $fileInfos = fopen($filePath, "r"); $newFilePath = ExcelUtil::getDownloadFile($filePath); $productNames = $infos = []; while (!feof($fileInfos)) { $fileInfo = Json::decode(fgets($fileInfos), true); if (!empty($fileInfo)) { if (in_array($fileInfo['productName'], $productNames) || empty($productNames)) { $infos[] = $fileInfo; $productNames[] = $fileInfo['productName']; } else { $args = [$infos, $params]; self::writeCsv($classFunction, $args, $header, $newFilePath); unset($infos, $productNames); $productNames[] = $fileInfo['productName']; $infos[] = $fileInfo; } } } if (!empty($infos)) { $args = [$infos, $params]; self::writeCsv($classFunction, $args, $header, $newFilePath); unset($productNames, $infos); } fclose($fileInfos); LogUtil::info(['message' => 'End to read csv file and end to write file', 'fileName' => $filePath], 'resque'); }
private function issueBirthdayCoupon($accountId, $birthdayCoupon, $memberId) { //check coupon $couponId = $birthdayCoupon->couponId; $suitMemberIds = $this->getRewardMemberIds($accountId, $memberId, $birthdayCoupon); if (!empty($suitMemberIds)) { $members = Member::findAll(['_id' => ['$in' => $suitMemberIds]]); $coupon = Coupon::findByPk($couponId); if (empty($coupon)) { LogUtil::error(['message' => 'can not find the coupon', 'couponId' => (string) $couponId], 'member'); return false; } $total = count($members); $result = Coupon::updateAll(['$inc' => ['total' => 0 - $total]], ['total' => ['$gt' => $total], '_id' => $couponId]); if ($result) { foreach ($members as $member) { //issue membershipdiscount $membershipDiscount = MembershipDiscount::transformMembershipDiscount($coupon, $member, ScoreRule::NAME_BIRTHDAY); if (false === $membershipDiscount->save()) { Coupon::updateAll(['$inc' => ['total' => 1]], ['_id' => $couponId]); LogUtil::error(['message' => 'add membershipdiscount fail', 'memberId' => (string) $member->_id, 'couponId' => (string) $coupon->_id], 'member'); } else { LogUtil::info(['message' => 'issue coupon successful', 'couponId' => (string) $couponId, 'memberId' => (string) $member->_id], 'member'); } } } else { LogUtil::error(['message' => 'coupon is not enough when give member birthday reward'], 'member'); return false; } } }
public static function createStatsCouponLog($dateStr, $stats) { //check data whether exists today $result = ModelStatsCouponLogDaily::findOne(['date' => $dateStr]); if ($result) { LogUtil::info(['message' => $dateStr . ' coupon log data is exists'], 'resque'); return true; } $stats = CouponLog::formatStruct($stats); $data = $couponIds = []; foreach ($stats as $stat) { $receivedKey = $stat['couponId'] . '_' . CouponLog::RECIEVED; $redeemedKey = $stat['couponId'] . '_' . CouponLog::REDEEMED; if (!in_array($stat['couponId'], $couponIds)) { $couponIds[] = $stat['couponId']; $receivedNum = isset($stats[$receivedKey]['count']) ? $stats[$receivedKey]['count'] : 0; $redeemedNum = isset($stats[$redeemedKey]['count']) ? $stats[$redeemedKey]['count'] : 0; $data[] = ['couponId' => $stat['couponId'], 'accountId' => $stat['accountId'], 'recievedNum' => $receivedNum + $redeemedNum, 'redeemedNum' => $redeemedNum, 'date' => $dateStr]; } } unset($stat, $stats, $couponIds); if (false === ModelStatsCouponLogDaily::batchInsert($data)) { LogUtil::error(['message' => 'Faild to create statis daily couponlog', 'date' => $dateStr, 'data' => json_encode($data)], 'resque'); } }
public function handle($data) { parent::handle($data); # handle the wechat message LogUtil::info(['channel weconnect event' => $data], 'channel-webhook'); if (empty($data)) { throw new BadRequestHttpException(Yii::t('channel', 'parameter_format_error')); } $data = $data['data']; $requiredParameters = ['outTradeNo', 'tradeNo', 'tradeStatus']; ValidatorUtil::fieldsRequired($data, $requiredParameters); $tradePayment = TradePayment::findOne(['orderNumber' => $data['outTradeNo']]); LogUtil::info(['tradePayment' => $tradePayment->toArray()], 'channel-webhook'); if (empty($tradePayment)) { throw new InvalidParameterException(Yii::t('common', 'data_error')); } $memberId = $tradePayment['user']['memberId']; $couponId = $tradePayment['couponId']; LogUtil::info(['memberId' => $memberId, 'couponId' => $couponId], 'channel-webhook'); if ($data['tradeStatus'] == 'PAY_SUCCESS') { $tradePayment->status = TradePayment::STATUS_PAID; $tradePayment->realAmount = intval($data['totalFee']) / 100; // Make coupon used if (!empty($couponId)) { Yii::$app->service->coupon->makeUsed($memberId, $couponId); } } else { if ($data['tradeStatus'] == 'PAY_ERROR') { $tradePayment->status = TradePayment::STATUS_FAILED; } } $tradePayment->paymentTime = MongodbUtil::msTimetamp2MongoDate($data['paymentTime']); $tradePayment->transactionId = $data['tradeNo']; return $tradePayment->save(true, ['paymentTime', 'status', 'transactionId', 'realAmount']); }
public function actionFrontend() { $params = $this->getQuery(); if (self::ERROR_TYPE === $params[self::PARAM_TYPE]) { LogUtil::error($params, self::FRONTEND); } else { LogUtil::info($params, self::FRONTEND); } header(self::IMAGE_CONTENT_TYPE); }
/** * validate go api signature * @return boolean */ private function validateSignature() { $request = Yii::$app->request; $bodyStr = $request->getRawBody(); $headers = $request->getHeaders(); //for golang $signature = hash_hmac('sha256', $bodyStr, 'Zc6smtltqrAToO44awoutxdS7LNsA81k'); LogUtil::info(['signature' => $signature, 'header' => $headers['X-Event-Signature'], 'body' => $bodyStr], 'event'); if (!empty($headers['X-Event-Signature']) && $signature === $headers['X-Event-Signature']) { return true; } else { return false; } }
/** * Send mobile message. * @param string $mobile The phone number * @param string $text, The message content. * @return Array */ public static function sendMobileMessage($mobile, $text) { $url = YUNPIAN_DOMAIN; $params = ['apikey' => YUNPIAN_API_KEY, 'mobile' => $mobile, 'text' => $text]; Yii::$app->curl->setHeaders(['Content-Type: application/x-www-form-urlencoded']); $resultJson = Yii::$app->curl->post($url, http_build_query($params)); LogUtil::info(['url' => $url, 'params' => $params, 'response' => $resultJson], 'mobile-message'); $result = Json::decode($resultJson, true); if ($result && isset($result['code']) && 0 == $result['code'] && isset($result['result']) && isset($result['result']['count']) && $result['result']['count'] > 0) { self::recoreMessageCount('omni_record_message_total'); return true; } else { LogUtil::error(['url' => $url, 'params' => $params, 'response' => $resultJson], 'mobile-message'); return false; } }
public function perform() { $args = $this->args; if (empty($args['type'])) { $types = [PromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_PARTICIPATE, PromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_TOTAL, PromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_EVERYDAY_PRIZE, PromotionCodeAnalysis::PROMOTION_CODE_ANALYSIS_TOTAL_PARTICIPATE]; foreach ($types as $type) { $yesterdayStamp = TimeUtil::today() - 24 * 3600; self::setData($type, $yesterdayStamp); LogUtil::info(['message' => 'run stats PromotionCodeAnalysis, type :' . $type], 'resque'); } } else { $type = intval($args['type']); $yesterdayStamp = TimeUtil::today() - 24 * 3600; self::setData($type, $yesterdayStamp); } return true; }
/** * Request the service with basic auth * @param string $url requested url * @param string $method requested method * @param string $params requested parameters */ private function _requestService($url, $method, $params = NULL) { //format header and params for post and put if (in_array($method, [self::METHOD_POST, self::METHOD_PUT])) { $method = $method . 'Json'; $params = Json::encode($params); } $resultJson = Yii::$app->curl->{$method}($url, $params); $logUrl = strtoupper($method) . ' ' . $url; $logTarget = 'webhook'; LogUtil::info(['url' => $logUrl, 'response' => $resultJson, 'params' => $params], $logTarget); if (StringUtil::isJson($resultJson)) { return Json::decode($resultJson, true); } else { LogUtil::error(['url' => $logUrl, 'response' => $resultJson, 'params' => $params], $logTarget); } }
public function actionAuth() { $secret = TUISONGBAO_SECRET; $socketId = $this->getParams('socketId'); $channelName = $this->getParams('channelName'); $authData = $this->getParams('authData'); $parts = explode(':', $authData); $clientId = $parts[1]; $userData = ['userId' => $clientId, 'userInfo' => []]; $userDataJsonStr = json_encode($userData); $strToSign = $socketId . ':' . $channelName . ':' . $userDataJsonStr; LogUtil::info(['strToSign' => $strToSign, 'secret' => $secret], 'signature'); $signature = hash_hmac('sha256', $strToSign, $secret); LogUtil::info(['signature' => $signature, 'channelData' => $userDataJsonStr], 'signature'); $result = ['signature' => $signature, 'channelData' => $userDataJsonStr]; header("Content-Type:application/json"); echo json_encode($result); }
/** * Create a job and put it in global queue * @param string $className * @param array $args * @param timestamp $executeTime UNIX timestamp when job should be executed, default is now * @param int $span seconds * @return string|null job token or empty */ public function create($className, $args = [], $executeTime = null, $interval = null, $isGlobal = true) { LogUtil::info(['message' => 'Begin a job', 'args' => $args], 'resque'); $queue = $isGlobal ? self::GLOBAL_QUEUE : self::BACKEND_QUEUE; $args['language'] = Yii::$app->language; if (!empty($executeTime)) { if (!empty($interval)) { $args['cron_job_time_interval'] = '+ ' . $interval . ' seconds'; while ($executeTime < time()) { $executeTime = strtotime($args['cron_job_time_interval'], $executeTime); } $args['cron_job_execute_time'] = $executeTime; } return Yii::$app->resque->enqueueJobAt($executeTime, $queue, $className, $args); } else { return Yii::$app->resque->createJob($queue, $className, $args); } }
/** * @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; }
/** * @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; }
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: update Stats of coupon"} */ public function perform() { $args = $this->args; $startTime = strtotime($args['startTime']); $endTime = strtotime($args['endTime']); $current = strtotime(date('Y-m-d')); if ($endTime > $current) { $endTime = $current; } for ($t = $startTime; $t <= $endTime; $t += 3600 * 24) { $dateStr = date('Y-m-d', $t); ModelStatsCouponLogDaily::deleteAll(['date' => $dateStr]); $stats = CouponLog::getStats($dateStr); if (!empty($stats)) { StatsCouponLogDaily::createStatsCouponLog($dateStr, $stats); } LogUtil::info(['message' => $dateStr . ': Update StatsCouponLogDaily'], 'update_coupon_log'); } 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; }
/** * This method is used to push message. * If mobile help-desk client is on backend, push message. */ public function pushMessage($deskId, $eventType, $extra, $message = null) { $cache = \Yii::$app->cache; $deskStrId = $deskId . ''; //Update the helpdesk unread message count $count = $cache->get(ConversationController::UNREAD_COUNT_PREFIX . $deskStrId); empty($count) && ($count = 0); $desk = HelpDesk::findByPk($deskId); if (empty($desk->deviceToken) || empty($desk->environment)) { LogUtil::info(['push' => 'missing device token', 'desk' => $deskId, 'eventType' => $eventType, 'extra' => $extra]); } else { if ($eventType == ConversationController::EVENT_CHAT_MESSAGE && $this->isPushMessage($deskId, $desk->accountId)) { $cache->set(ConversationController::UNREAD_COUNT_PREFIX . $deskStrId, ++$count); } else { //no code here, push state like 'sessionConnected', no need to add $count } $extra['type'] = $eventType; $target = [$desk->environment => [$desk->deviceToken]]; \Yii::$app->tuisongbao->pushMessage($target, $count, $extra, $message); } }
public function perform() { $args = $this->args; if (empty($args['accountId']) || empty($args['key']) || empty($args['header']) || empty($args['collection']) || empty($args['fields'])) { LogUtil::info(['message' => 'fail to export klp member, missing params', 'args' => $args], 'resque'); return false; } $fileName = $args['key']; $filePath = ExcelUtil::getFile($fileName, 'csv'); $condition = ExcelUtil::processCondition(unserialize($args['condition'])); ExcelUtil::exportWithMongo($args['collection'], $args['fields'], $filePath, $condition); $classFunction = '\\backend\\modules\\member\\models\\Member::preProcessKlpMemberData'; $headerKeys = array_keys($args['header']); ExcelUtil::processRowsData($args['header'], $filePath, $classFunction, $headerKeys); $newFilePath = ExcelUtil::getDownloadFile($filePath); $downloadFilePath = self::getFile($fileName); copy($newFilePath, $downloadFilePath); @unlink($newFilePath); @unlink($filePath); //notice frontend the job is finished Yii::$app->tuisongbao->triggerEvent(Message::EVENT_EXPORT_FINISH, ['key' => $fileName], [Message::CHANNEL_GLOBAL . $args['accountId']]); }
/** * Upload file to qiniu cloud * @param string $filePath file path * @param string $key file name in qiniu * @param bool $isAllowedOverwrite */ public function upload($filePath, $key, $isAllowedOverwrite = false) { if ($isAllowedOverwrite) { $upToken = $this->getToken($key); } else { $upToken = $this->getToken(); } if (filesize($filePath) > 1 << self::QINIU_UPLOAD_BLOCK_BITS) { LogUtil::info(['message' => 'upload file use block', 'filePath' => $filePath], 'resque'); $putExtra = new \Qiniu_Rio_PutExtra(); list($ret, $err) = Qiniu_Rio_PutFile($upToken, $key, $filePath, $putExtra); } else { LogUtil::info(['message' => 'upload file directly', 'filePath' => $filePath], 'resque'); $putExtra = new \Qiniu_PutExtra(); $putExtra->Crc32 = 1; list($ret, $err) = Qiniu_PutFile($upToken, $key, $filePath, $putExtra); } if ($err !== null) { return $err; } else { return $ret; } }
public function perform() { # Run task $args = $this->args; if (empty($args['locationPath']) || empty($args['productId']) || empty($args['filePath']) || empty($args['accountId']) || empty($args['qiniuBucket']) || empty($args['fileName'])) { LogUtil::error(['message' => 'missing productId or filePath in PromotionCheckCode', 'params' => $args], 'resque_product'); } //get qiniu file, keep bom because of excel content $qiniuFile = Yii::$app->curl->get($args['filePath'], [], false); if (false === file_put_contents($args['locationPath'], $qiniuFile)) { LogUtil::error(['message' => 'Fail to get file from qiniu', 'args' => $args], 'resque_product'); return false; } $phpreader = \PHPExcel_IOFactory::createReader('Excel2007'); $filePath = $args['locationPath']; if (!$phpreader->canRead($filePath)) { $phpreader = \PHPExcel_IOFactory::createReader('Excel5'); if (!$phpreader->canRead($filePath)) { $phpreader = \PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',')->setInputEncoding('GBK')->setEnclosure('"')->setLineEnding("\r\n")->setSheetIndex(0); if (!$phpreader->canRead($filePath)) { LogUtil::error(['message' => 'FIle can not read in PromotionCheckCode'], 'resque_product'); return false; } LogUtil::info(['message' => 'Use Csv', 'filePath' => $filePath], 'resque_product'); } else { LogUtil::info(['message' => 'Use Excel5', 'filePath' => $filePath], 'resque_product'); } } else { LogUtil::info(['message' => 'Use Excel2007', 'filePath' => $filePath], 'resque_product'); } $phpexcel = $phpreader->load($filePath); //read excel the first table $currentSheet = $phpexcel->getSheet(0); //get total row num $allRow = $currentSheet->getHighestRow(); //product sku $productId = $args['productId']; //make a key to be called a name for redis set $cacheSet = self::SET_HEAD . md5($args['accountId'] . "_" . $productId . "_" . $args['fileName']); //make a key to be called a name for redis hash $cacheHash = md5($args['accountId'] . "_" . $productId . "_" . $args['fileName']); //the key for wrong number for store in redis $wrongKey = 'wrong'; //the key for right number for store in redis $rightKey = 'right'; $total = $wrong = $right = 0; $redis = Yii::$app->cache->redis; $redis->expire($cacheHash, self::EXPIRE); LogUtil::info(['message' => 'get file info', 'allRow' => $allRow, 'sku' => $productId, 'cacheSet' => $cacheSet, 'cacheHash' => $cacheHash], 'resque_product'); for ($rowIndex = 2; $rowIndex <= $allRow; ++$rowIndex) { //get productid $A = 'A' . $rowIndex; //get code $B = 'B' . $rowIndex; $Acell = trim($currentSheet->getCell($A)->getValue()); $Bcell = strtoupper(trim($currentSheet->getCell($B)->getValue())); if ($Acell != $productId && !empty($Bcell) && !empty($Acell)) { LogUtil::error(['error' => 'the product number in the excel is not equal the selected product number', 'args' => ['cell' => $Acell, 'sku' => $productId]], 'resque_product'); // $wrong++; $redis->Hset($cacheHash, $wrongKey, self::PRODUCT_SKU_WRONG); $redis->Hset($cacheHash, $rightKey, 0); return false; } else { if (!empty($Acell) && !empty($Bcell)) { $total++; $redis->sadd($cacheSet, $Bcell); } } } if ($total <= 0) { LogUtil::info(['message' => 'no datas'], 'resque_product'); } //store the number of the wrong code and the number of the right code $right = $redis->scard($cacheSet); $wrong = $total - $right; $redis->Hset($cacheHash, $wrongKey, $wrong); $redis->Hset($cacheHash, $rightKey, $right); unlink($filePath); Yii::$app->qiniu->deleteFile($args['fileName'], $args['qiniuBucket']); return true; }
/** * Follower bind to be a member. * * <b>Request Type</b>: POST<br/><br/> * <b>Request Endpoint</b>:http://{server-domain}/api/mobile/bind<br/><br/> * <b>Response Content-type</b>: application/json<br/><br/> * <b>Summary</b>: This api is used for follower bind. * <br/><br/> * * <b>Request Params</b>:<br/> * mobile: string<br/> * openId: string<br/> * unionId: string<br/> * channelId: string<br/> * captcha: string<br/> * <br/><br/> * * <b>Response Params:</b><br/> * <br/><br/> * * <br/><br/> * * <b>Response Example</b>:<br/> * <pre> * { * "message": "OK", * "data": "http://wm.com?memberId=55d29e86d6f97f72618b4569" * </pre> */ public function actionBind() { //set language zh_cn when bind Yii::$app->language = LanguageUtil::LANGUAGE_ZH; $params = $this->getParams(); if (empty($params['mobile']) || empty($params['openId']) || empty($params['channelId']) || empty($params['captcha'])) { throw new BadRequestHttpException('missing param'); } $isTest = false; if ($params['mobile'] == self::TEST_PHONE && $params['captcha'] == self::TEST_CODE) { $isTest = true; } else { $this->attachBehavior('CaptchaBehavior', new CaptchaBehavior()); $this->checkCaptcha($params['mobile'], $params['captcha']); } //get accountId $openId = $params['openId']; $channel = Channel::getEnableByChannelId($params['channelId']); $origin = $channel->origin; $accountId = $channel->accountId; //create accessToken $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 member has bind if (empty($params['unionId'])) { $member = Member::getByOpenId($openId); } else { $unionId = $params['unionId']; $member = Member::getByUnionid($unionId); } if (!empty($member)) { $memberId = (string) $member->_id; $url = $this->buildBindRedirect($memberId, $params); return ['message' => 'OK', 'data' => $url]; } //check mobile has been bind $member = Member::getByMobile($params['mobile'], new \MongoId($accountId)); if (!empty($member)) { throw new InvalidParameterException(['phone' => Yii::t('common', 'phone_has_been_bound')]); } $follower = Yii::$app->weConnect->getFollowerByOriginId($openId, $params['channelId']); $originScene = empty($follower['firstSubscribeSource']) ? '' : $follower['firstSubscribeSource']; //init avatar and location $avatar = !empty($follower['headerImgUrl']) ? $follower['headerImgUrl'] : Yii::$app->params['defaultAvatar']; $location = []; !empty($follower['city']) ? $location['city'] = $follower['city'] : null; !empty($follower['province']) ? $location['province'] = $follower['province'] : null; !empty($follower['country']) ? $location['country'] = $follower['country'] : null; LogUtil::info(['message' => 'get follower info', 'follower' => $follower], 'channel'); //init member properties $memberProperties = MemberProperty::getByAccount($accountId); $propertyMobile = []; $propertyGender = []; $propertyName = []; $properties = []; foreach ($memberProperties as $memberProperty) { if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_MOBILE) { $propertyMobile['id'] = $memberProperty['_id']; $propertyMobile['name'] = $memberProperty['name']; $propertyMobile['value'] = $params['mobile']; $properties[] = $propertyMobile; } if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_GENDER) { $propertyGender['id'] = $memberProperty['_id']; $propertyGender['name'] = $memberProperty['name']; $propertyGender['value'] = !empty($follower['gender']) ? strtolower($follower['gender']) : 'male'; $properties[] = $propertyGender; } if ($memberProperty['name'] == Member::DEFAULT_PROPERTIES_NAME) { $propertyName['id'] = $memberProperty['_id']; $propertyName['name'] = $memberProperty['name']; $propertyName['value'] = $follower['nickname']; $properties[] = $propertyName; } } //get default card $card = MemberShipCard::getDefault($accountId); $memberId = new \MongoId(); $memberAttribute = ['$set' => ['_id' => $memberId, 'avatar' => $avatar, 'cardId' => $card['_id'], 'location' => $location, 'score' => 0, 'socialAccountId' => $params['channelId'], 'properties' => $properties, 'openId' => $openId, 'origin' => $origin, 'originScene' => $originScene, 'unionId' => empty($unionId) ? '' : $unionId, 'accountId' => $accountId, 'cardNumber' => Member::generateCardNumber($card['_id']), 'cardProvideTime' => new \MongoDate(), 'createdAt' => new \MongoDate(), 'socials' => [], 'isDeleted' => false]]; if (!$isTest) { $result = Member::updateAll($memberAttribute, ['openId' => $openId], ['upsert' => true]); } else { $result = true; } if ($result) { // reword score first bind card $this->attachBehavior('MemberBehavior', new MemberBehavior()); $this->updateItemByScoreRule(Member::findByPk($memberId)); Yii::$app->qrcode->create(Yii::$app->request->hostInfo, Qrcode::TYPE_MEMBER, $memberId, $accountId); $memberId = (string) $memberId; $url = $this->buildBindRedirect($memberId, $params); return ['message' => 'OK', 'data' => $url]; } else { LogUtil::error(['error' => 'member save error', 'params' => Json::encode($member)], 'member'); throw new ServerErrorHttpException("bind fail"); } }
public function actionGetOneCookbookById() { $accountId = $this->getAccountId(); $cookbookId = $request = Yii::$app->request->get("cookbookId", ""); $mobile = Yii::$app->request->get('mobile', null); $query = new Query(); $query->from('uhkklpCookbook')->select(['_id', 'title', 'image', 'content', 'ingredient', 'startDate', 'endDate', 'shareUrl', 'isSampleOpen', 'sample', 'active', 'createdDate', 'updatedDate', 'operator', 'type', 'video', 'restaurantName', 'cookName', 'category', 'subCategory', 'portionSize', 'preparationMethod', 'yield', 'creativeExperience', 'deliciousSecret', 'cuisineType', 'averageScore'])->where(['_id' => $cookbookId]); $cookbook = $query->one(); if ($cookbook == false) { return ['code' => 1204, 'msg' => 'cookbook not found.']; } $cookbook = $this->formatCookbook($cookbook); $cookbook = $this->formatCookbookForAPI($cookbook); if ($mobile != null && strlen($mobile) != 0) { //collection and score $query = new Query(); $query->from('uhkklpUserCookbook')->where(['mobile' => $mobile, 'isDeleted' => false, 'accountId' => $accountId]); $userCookbook = $query->all(); $cookbook['collection'] = 'N'; $cookbook['score'] = 0; for ($j = 0; $j < count($userCookbook); $j++) { if ($userCookbook[$j]['cookbookId'] == $cookbook['cookbookId']) { if (!isset($userCookbook[$j]['collection'])) { $userCookbook[$j]['collection'] = 'N'; } else { if ($userCookbook[$j]['collection'] != 'N') { $userCookbook[$j]['collection'] = 'Y'; } } if (!isset($userCookbook[$j]['score'])) { $userCookbook[$j]['score'] = 0; } $cookbook['collection'] = $userCookbook[$j]['collection']; $cookbook['score'] = $userCookbook[$j]['score']; break; } } //samplerecord $query = new Query(); $query->from('uhkklpSamplerecord')->where(['mobile' => $mobile, 'isDeleted' => false, 'accountId' => $accountId]); $record = $query->all(); $sample = $cookbook['sample']; for ($j = 0; $j < count($sample); $j++) { for ($k = 0; $k < count($record); $k++) { if ($record[$k]['sampleId'] == $sample[$j]['id']) { $sample[$j]['getSampled'] = 'Y'; break; } } if ($k >= count($record)) { $sample[$j]['getSampled'] = 'N'; } } $cookbook['sample'] = $sample; } $result['cookbook'] = $cookbook; LogUtil::info('GetOneCookbookById' . ' mobile:' . $mobile, 'cookbook-log'); Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; return ['code' => 200, 'msg' => 'OK', 'result' => $result]; }
public function actionOpenWechatPayment() { $params = $_POST; $file = $_FILES; $accountId = $this->getAccountId(); if (empty($params['appId']) || empty($params['sellerId']) || empty($params['apiKey']) || empty($file['p12Credential']) || empty($file['pemCredentialKey']) || empty($file['pemCredential']) || empty($file['caCredential']) || empty($params['weconnectAccountId'])) { throw new BadRequestHttpException(Yii::t('common', 'parameters_missing')); } $condition = array('appId' => $params['appId'], 'sellerId' => $params['sellerId'], 'apiKey' => $params['apiKey'], 'weconnectAccountId' => $params['weconnectAccountId'], 'quncrmAccountId' => (string) $accountId, 'p12Credential' => "@{$file['p12Credential']["tmp_name"]};type={$file['p12Credential']['type']};filename={$file['p12Credential']['name']}", 'pemCredentialKey' => "@{$file['pemCredentialKey']['tmp_name']};type={$file['pemCredentialKey']['type']};filename={$file['pemCredentialKey']['name']}", 'pemCredential' => "@{$file['pemCredential']['tmp_name']};type={$file['pemCredential']['type']};filename={$file['pemCredential']['name']}", 'caCredential' => "@{$file['caCredential']['tmp_name']};type={$file['caCredential']['type']};filename={$file['caCredential']['name']}", 'paymentStatus' => 'ENABLE'); $result = Yii::$app->weConnect->openWechatPayment($condition); if (!empty($result) && empty($result['message']) == 'OK') { $channelId = $params['weconnectAccountId']; LogUtil::info(['accountId' => (string) $accountId, 'channelId' => $channelId], 'reservation'); Yii::$app->webhookEvent->subscribeMsg('channel', $channelId, WebhookEvent::DATA_TYPE_MSG_PAYMENT, time()); return ['authDirectory' => DOMAIN . self::WECHAT_PAYMENT_DIRECTORY]; } else { LogUtil::error(['message' => 'Failed to open wechat payment', 'data' => $result], 'channel'); } }
/** * Used for tuisongbao web hook, realtime engine will call the service when user subscribe or unsubscribe a channel * @return string json status */ public function actionUserState() { $body = $this->getParams(); $headers = Yii::$app->request->getHeaders(); $signature = hash_hmac('sha256', json_encode($body), TUISONGBAO_SECRET); LogUtil::info(['body' => $body, 'signature' => $signature], 'webhook'); // Check whether it is called by the tuisongbao web hook if ($signature === $headers['X-Engine-Signature']) { //TODO: First event may not be the correct one $time = $body['timestamp']; $event = $body['events'][0]; $userId = $event['userId']; $eventName = $event['name']; //Tip: Only handle the user_removed event on global channel here if (strpos($event['channel'], ChatConversation::CHANNEL_GLOBAL) !== false && ChatConversation::MONGOID_LENGTH === strlen($userId)) { $helpdesk = HelpDesk::findByPk(new \MongoId($userId)); if (!empty($helpdesk)) { if ($eventName == ChatConversation::EVENT_USER_ADDED || $eventName == ChatConversation::EVENT_USER_REMOVED) { $updateTimePrefix = 'wm-update-time'; $cache = Yii::$app->cache; $lastTime = $cache->get($updateTimePrefix . $userId); // failed events will be send again, but timestamp will not change // if a event is failed and other event has success, skip that failed event // Event_1. user_add failed; Event_2, user_remove successed; Event_1. user_add successed // skip Event_1. user_add successed if (empty($lastTime) || $lastTime < $time) { $cache->set($updateTimePrefix . $userId, $time); HelpDesk::cacheOnlineDesks($helpdesk->_id . '', $helpdesk->accountId . '', $eventName); } } } } } }
/** * Using a post request to call weibo api * @param string $url request url * @param string $logTarget log file directory * @param string $resultField the flag of the success request * @param string $params request parameters * @param boolean $returnResultData * @throws ApiDataException */ private function _post($url, $logTarget, $resultField, $params = [], $returnResultData = true) { $resultJson = null; if (count($params) == 0) { $resultJson = Yii::$app->curl->post($url); } else { $resultJson = Yii::$app->curl->postJson($url, $params); } LogUtil::info(['url' => 'POST ' . $url, 'params' => $params, 'response' => $resultJson], $logTarget); $result = json_decode($resultJson, true); if ($result && isset($result[$resultField])) { if ($returnResultData) { return $result; } else { return true; } } else { throw new ApiDataException("POST " . $url, $resultJson); } }
/** * Create a new Token * @param Object $user, instance of model User * @author Devin Jin * */ public static function create($user) { $account = Account::findOne(['_id' => $user->accountId]); if (!empty($account)) { $token = new Token(); $token->accessToken = StringUtil::uuid(); $token->expireTime = new \MongoDate(time() + self::EXPIRE_TIME); $token->userId = $user['_id']; $token->accountId = $account['_id']; $token->language = $user['language']; $token->enabledMods = empty($account['enabledMods']) ? [] : $account['enabledMods']; $token->role = $user['role']; if ($token->save()) { LogUtil::info(['message' => 'create new token for wechat', 'accessToken' => $token->accessToken]); return $token; } } return false; }
/** * check the code in the excel */ public function actionCheckCode() { $params = Yii::$app->request->post(); $productId = $params['productId']; //$productId = '1429862376675049'; if (empty($productId)) { throw new BadRequestHttpException('missing param productId'); } $fileKey = 'file'; if (empty($_FILES[$fileKey])) { throw new BadRequestHttpException('missing param ' . $fileKey); } $accountId = $this->getAccountId(); $where = ['accountId' => $accountId, 'sku' => $productId]; $result = Product::findOne($where); LogUtil::info(['file' => $_FILES, 'where' => $where], 'promotimeCode'); if (empty($result)) { throw new BadRequestHttpException(Yii::t("product", "product_deleted")); } unset($where); //upload config $config = ['maxSize' => self::MAXSIZE, 'allowFiles' => self::$ALLOWFILES, 'pathFormat' => self::PATHFORMAT, 'privateBucket' => true]; //upload to qiniu $upload = new Uploader($fileKey, $config, 'upload', 1); $fileInfo = $upload->getFileInfo(); $rootPath = Yii::$app->getRuntimePath() . '/code/'; if (!is_dir($rootPath)) { FileHelper::createDirectory($rootPath, 0777, true); } $fileName = $fileInfo['title']; $locationPath = $rootPath . $fileName . $fileInfo['type']; if (empty($fileName)) { throw new InvalidParameterException($fileInfo['state']); } $checkArgs = ['qiniuBucket' => QINIU_DOMAIN_PRIVATE, 'productId' => $productId, 'filePath' => Yii::$app->qiniu->getPrivateUrl($fileName), 'locationPath' => $locationPath, 'fileName' => $fileName, 'accountId' => (string) $accountId, 'description' => 'Direct: Check if promotion codes to be imported is unique']; $jobId = Yii::$app->job->create('backend\\modules\\product\\job\\PromotionCheckCode', $checkArgs); return ['message' => 'OK', 'data' => ['token' => $jobId, 'filename' => $fileName]]; }
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'); } }
/** * Get wehcat pay signature * * Request Method: * * POST * * Request Parameters: * * { * "quncrmAccountId": "群脉账号ID", * "params": { * "key1": "value1", * "key2": "value2", * "key3": "value3", * } * } * * Response Body: * * { * "code": 200, * "message": "OK", * "data": { * "appId": "公众账号ID", * "signType": "DSA、RSA、MD5", * "paySign": "signString" * } * } * @return [type] [description] */ public function getWechatPaySignature($accountId, $prepayId, $appId) { $url = $this->weconnectDomain . '/weixin/pay/sign'; $timestamp = time(); $nonceStr = StringUtil::rndString(16, StringUtil::ALL_DIGITS_LETTERS); $params = ['timeStamp' => $timestamp, 'nonceStr' => $nonceStr, 'package' => "prepay_id={$prepayId}", 'appId' => $appId, 'signType' => 'MD5']; $data = ['quncrmAccountId' => (string) $accountId, 'params' => $params]; LogUtil::info(['wechat signature data' => $data], 'reservation'); $result = Yii::$app->curl->postJson($url, json_encode($data)); $result = json_decode($result, true); LogUtil::info(['wechat signature result' => $result], 'reservation'); if (!empty($result) && $result['code'] === 200 && !empty($result['data'])) { $params['appId'] = $result['data']['appId']; $params['signType'] = $result['data']['signType']; $params['paySign'] = $result['data']['paySign']; return $params; } }
/** * redirect to receive coupon page * @param $level,log level * @param $message,string * @param $args,array, args must include these key:mainDomain,couponId,id,memberId,result,channelId */ private function _redirectCouponDetail($message, $args, $params) { extract($args); $url = $mainDomain . '?couponId=' . $couponId . '&id=' . $id . '&memberId=' . $memberId . '&result=' . $result . '&message=' . $message . '&channelId=' . $channelId; LogUtil::info(['message' => $message, 'url' => $url, 'params' => $params], 'product'); return $this->redirect($url); }