public function ihm() { $now = time(); $query = Member::find()->from(self::tableName() . ' member')->where(['and', 'regtime>1439879084', "regtime<{$now}"])->asArray()->select(['member.*', 'mdetail.sex', 'mdetail.company'])->leftJoin(MemberDetail::tableName() . ' mdetail', 'member.userid=mdetail.userid'); // ->groupBy(['member.mobile']); // $query = $query->from(Member::tableName()); $user = new UserBaseInfo(); // $user_openid = new UserOpenid(); $fileLogger = FileLogger::getInstance('iheima.log'); foreach ($query->batch(1000, Yii::$app->iheima) as $rows) { $params = []; $openId = []; if (!arr_null($rows)) { foreach ($rows as $row) { $openIds = openId('iHeiMa'); $params[] = ['username' => $row['username'], 'password' => $row['password'], 'password_salt' => $row['salt'], 'mobile' => $row['mobile'], 'email' => $row['email'], 'gender' => $row['sex'], 'reg_ip' => $row['regip'], 'last_login_time' => $row['lastlogintime'], 'last_login_ip' => $row['lastloginip'], 'create_time' => $row['regtime'], 'update_time' => time(), 'status' => $row['status'], 'open_id' => $openIds]; $openId[] = ['openid' => $openIds, 'userid' => $row['userid'], 'flag' => 'iheima']; } $result = $user->batchInsertUser($params); if (!$result) { $fileLogger->writeOne('同步失败' . json_encode($row['email']), Logger::LEVEL_INFO, 'iHeiMa用户同步失败'); return false; } // $rt = $user_openid->batchInsert($openId); // if (!$rt) { // return false; // } //$fileLogger->writeOne('同步成功' . json_encode($params), Logger::LEVEL_INFO, 'iHeiMa用户同步成功'); } } $fileLogger->writeOne(json_encode($openId), Logger::LEVEL_INFO, 'iHeiMa用户openId与用户id对应关系数据'); return $openId; }
/** * 获取所有绑定短信服务的应用ID * @param string $serviceId 服务标识 * * @return array */ public function getAllServiceId($appId) { $serviceId = []; $serviceIds = self::find()->select(['service_id'])->distinct()->where(['status' => self::BINDING])->andWhere(['app_Id' => $appId])->orderBy('service_id')->asArray()->all(); if (is_array($serviceIds) && !arr_null($serviceIds)) { foreach ($serviceIds as $service) { $serviceId[] = $service['service_id']; } } return $serviceId; }
/** * 计算短信某一时间段的发送总量 * * @param array $sms 从redis取出的短信发送记录信息 * * @return int */ function count_sms_sum($sms) { $total = 0; if (!is_array($sms) || arr_null($sms)) { return $total; } array_walk_recursive($sms, function ($value, $key) use(&$total) { if ($key % 2 != 0) { $total += intval($value); } }); return $total; }
public function beforeAction($action) { if ($action->actionMethod == 'actionWxNotify') { $action->controller->enableCsrfValidation = false; } $alipay = Yii::$app->alipay; $wxpay = Yii::$app->wxpay; $request = Yii::$app->getRequest(); $get = $request->get(); $appId = isset($get['app_id']) && $get['app_id'] ? $get['app_id'] : '100002'; if (!$appId) { // app_id 为必须参数 die('app_id required'); } $sso = new SsoSettingInfo(); $mch = $sso->getMchByAppid($appId); $mch = json_decode($mch['mch_info'], true); if (arr_null($mch)) { // TODO:: 应用sso配置中没有设置商户信息 die('mch information required'); } $wxpayi = $mch['wxpay']; $alipayi = $mch['alipay']; WxPayConfig::$appId = $wxpayi['app_id']; WxPayConfig::$appSecret = $wxpayi['app_secret']; WxPayConfig::$mchId = $wxpayi['mch_id']; WxPayConfig::$key = $wxpayi['key']; WxPayConfig::$sslcert_path = $wxpayi['sslcert_path']; WxPayConfig::$sslkey_path = $wxpayi['sslkey_path']; $alipay->sellerEmail = $alipayi['seller_email']; $alipay->partner = $alipayi['partner']; $alipay->key = $alipayi['key']; $login = UserBaseInfo::isLogin(); if ($login) { return parent::beforeAction($action); } return $this->redirect(['user/login']); }
/** * 业务维度批量统计 */ public function actionEmailBatchBusi() { try { $busiStat = new EmailStatBusiness(); $serviceBinding = new ServiceBinding(); // 所有应用系统app_id $appIdAll = $serviceBinding->getAllAppId(self::SERVICEID); if (empty($appIdAll)) { $this->stdout("不存在通过审核的第三方应用系统!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("不存在通过审核的第三方应用系统!!!", Logger::LEVEL_INFO, 'console\\controllers\\EmailController::email-batch-busi'); exit(6); } // 邮件业务信息 $business = EmailBusinessCategory::find()->where(['status' => 1])->orderBy('app_id')->asArray()->all(); if (arr_null($business)) { $this->stdout("所有系统均没有绑定邮件业务ID!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("所有系统均没有绑定邮件业务ID!!!", Logger::LEVEL_INFO, 'console\\controllers\\EmailController::email-batch-busi'); exit(6); } // key为app_id value为邮件业务ID的数组 $appBusi = []; foreach ($business as $busi) { $appBusi[$busi['app_id']][] = $busi['id']; } foreach ($appIdAll as $key => $appId) { if (!isset($appBusi[$appId])) { unset($appIdAll[$key]); } } if (empty($appIdAll)) { $this->stdout("所有系统均没有绑定邮件业务ID!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("所有系统均没有绑定邮件业务ID!!!", Logger::LEVEL_INFO, 'console\\controllers\\EmailController::email-batch-busi'); exit(6); } $time = time(); $date = date('Ymd', time() - 24 * 60 * 60); $type = self::BUSI_CACHE_PREFIX; $keys = []; $i = 0; foreach ($appIdAll as $appIda) { foreach ($appBusi[$appIda] as $busiId) { $keys[$i]['key'] = $type . $appIda . ':' . $busiId . ':' . $date; $keys[$i]['id'] = $appIda . '' . $busiId . '' . $date; $keys[$i]['app_id'] = $appIda; $keys[$i]['busiId'] = $busiId; $i++; } } $redis = Yii::$app->redisCache->redis; $rows = []; $appIds = []; foreach ($keys as $key) { $total = 0; $appIds[] = $key['app_id']; if ($redis->exists($key['key'])) { $busis = $redis->hgetall($key['key']); if (!empty($busis)) { $total = count_sms_sum($busis); } } $rows[] = [$key['id'], $key['app_id'], $key['busiId'], $date, $total, $time, $time]; } $appIds = implode(',', array_unique($appIds)); $result = $busiStat->batchInsertStat($rows); if (!$result) { $this->stdout("应用ID为{$appIds}的应用系统业务维度统计失败!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("应用ID为{$appIds}的应用系统业务维度统计失败!!!", Logger::LEVEL_INFO, 'console\\controllers\\EmailController::email-batch-busi'); exit(3); } $this->stdout("应用ID为{$appIds}的应用系统业务维度统计成功!!!\r\n", Console::FG_GREEN); $this->_fileLogger->writeOne("应用ID为{$appIds}的应用系统业务维度统计成功!!!", Logger::LEVEL_INFO, 'console\\controllers\\EmailController::email-batch-busi'); // 清除缓存 foreach ($keys as $key) { $redis->del($key['key']); } exit; } catch (\Exception $ex) { $code = $ex->getCode(); if ($code == 23000) { $this->stdout("应用中存在已经被备份(主键重复)~~\r\n", Console::FG_RED); } else { $this->stdout("系统出错,请稍后重试~~\r\n", Console::FG_RED); } $this->_fileLogger->writeOne($ex->getMessage(), Logger::LEVEL_ERROR, 'console\\controllers\\EmailController::email-batch-daily'); // 1表示异常退出 exit(1); } }
/** * 构造数组,形如: * ~~~ * ['10001' => [应用配置数组], '10002' => [应用配置数组]] * ~~~ * * @param array $appConfigs * @return array */ protected function buildAppIdArray($appConfigs) { $config = []; if (is_array($appConfigs) && !arr_null($appConfigs)) { foreach ($appConfigs as $configs) { if (isset($configs['app_id'])) { $config[$configs['app_id']] = $configs; } } } return $config; }
/** * 根据短信服务配置短信验证 * * @param string $appid 应用系统ID * @param array $data 验证需要的参数 * * @return array [a,b] a代码 b具体信息 */ public function verifySetting($appid, $data, $isISystem) { // 获取文件缓存处理类 $cache = Yii::$app->getCache(); $settings = $cache->get('email:setting'); // 若缓存内容为空则查询数据库 if (!$settings || empty($settings)) { $appConfigs = EmailSettingInfo::find()->asArray()->all(); if (arr_null($appConfigs)) { return [0, 'success']; } $settings = $this->buildAppIdArray($appConfigs); $cacheResult = $cache->set('email:setting', $settings); if (!$cacheResult) { // TODO:: 缓存设置失败 } } if (!isset($settings[$appid])) { return [2202, 'error_appid_invalid']; } $setting = $settings[$appid]; if (!$isISystem) { // 若域名白名单不为空 if ($setting['domain_white_list']) { $domainWhiteList = json_decode($setting['domain_white_list'], true); // 若不在白名单内 if (!in_array($data['host'], $domainWhiteList)) { return [2007, 'error_domain_white_list']; } } // 若IP白名单不为空 if (isset($data['source']) || $setting['ip_white_list']) { $ipWhiteList = json_decode($setting['ip_white_list'], true); // 若不在白名单内 if (!in_array($data['source'], $ipWhiteList)) { return [2006, 'error_ip_white_list']; } } } $date = date('YmdH', time()); $key = 'EMAIL:MINUTE:' . $appid . ':' . $date; $minutes = date('i'); $failKey = 'EMAIL:STATUS:' . $appid . ':' . 0 . ':' . date('Ymd', time()); $userKey = 'EMAIL:RECUSER:'******':' . date('YmdH', time()); $userBusiKey = 'EMAIL:UBUSI:' . $appid . ':' . $data['busiID'] . ':' . date('Ymd', time()); $hour = date('H'); $redis = Yii::$app->redisCache->redis; // 用户业务每日接收上限控制 /* if ($data['ubusi_daily_upper_limit'] > 0) { $total = $redis->hget($userBusiKey, $data['mobile']); if ($total >= $data['ubusi_daily_upper_limit']) { return [2008, 'error_ubusi' . $data['busiID'] . '_upperlimit']; } } */ // 若应用每分钟发送上限大于0 if ($setting['app_minutely_send_limit'] > 0) { $total = $redis->hget($key, $minutes); if ($total > $setting['app_minutely_send_limit']) { return [2008, 'error_minutely_upperlimit']; } } // 若应用每小时发送上限大于0 if ($setting['app_hourly_send_limit'] > 0) { $result = $redis->hgetall($key); $total = count_sms_sum($result); if ($total >= $setting['app_hourly_send_limit']) { return [2003, 'error_hour_upperlimit']; } } // 失败小时上限 if ($setting['send_failed_hourly_limit']) { $total = $redis->hget($failKey, $hour); if ($total >= $setting['send_failed_hourly_limit']) { return [2010, 'error_hourly_fail_upperlimit']; } } // 失败天上限 if ($setting['send_failed_daily_limit']) { $result = $redis->hgetall($failKey); $total = count_sms_sum($result); if ($total >= $setting['send_failed_daily_limit']) { return [2009, 'error_daily_fail_upperlimit']; } } if ($setting['user_hourly_send_limit']) { foreach ($data['to'] as $key => $email) { $total = $redis->hget($userKey, $email); if ($total >= $setting['user_hourly_send_limit']) { return [2011, 'error_hourly_user_upperlimit ']; } } } // 用户每小时发送上限 return [0, $data]; }
/** * 业务维度批量统计 */ public function actionSmsBatchBusi() { try { $serviceBinding = new ServiceBinding(); // 所有应用系统app_id $appIdAll = $serviceBinding->getAllAppId(self::SERVICEID); if (empty($appIdAll)) { $this->stdout("不存在通过审核的第三方应用系统!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("不存在通过审核的第三方应用系统!!!", Logger::LEVEL_INFO, 'console\\controllers\\SmsController::sms-batch-busi'); exit(6); } // 短信业务信息 $business = SmsBusinessCategory::find()->asArray()->where(['status' => 1])->orderBy('app_id')->all(); if (arr_null($business)) { $this->stdout("所有系统均没有绑定短信业务ID!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("所有系统均没有绑定短信业务ID!!!", Logger::LEVEL_INFO, 'console\\controllers\\SmsController::sms-batch-busi'); exit(6); } // key为app_id value为短信业务ID的数组 $appBusi = []; foreach ($business as $busi) { $appBusi[$busi['app_id']][] = $busi['id']; } foreach ($appIdAll as $key => $appId) { if (!isset($appBusi[$appId])) { unset($appIdAll[$key]); } } if (empty($appIdAll)) { $this->stdout("所有系统均没有绑定短信业务ID!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("所有系统均没有绑定短信业务ID!!!", Logger::LEVEL_INFO, 'console\\controllers\\SmsController::sms-batch-busi'); exit(6); } $time = time(); $date = date('Ymd', time() - 24 * 60 * 60); $type = 'SMS:BUSI'; $keys = []; $i = 0; foreach ($appIdAll as $appIda) { foreach ($appBusi[$appIda] as $busiId) { $keys[$i]['key'] = $type . ':' . $appIda . ':' . $busiId . ':' . $date; $keys[$i]['id'] = $appIda . '' . $busiId . '' . $date; $keys[$i]['app_id'] = $appIda; $keys[$i]['busiId'] = $busiId; $i++; } } $redis = Yii::$app->redisCache->redis; $rows = []; $appIds = []; foreach ($keys as $key) { $total = 0; $appIds[] = $key['app_id']; if ($redis->exists($key['key'])) { $busis = $redis->hgetall($key['key']); if (!empty($busis)) { $total = count_sms_sum($busis); } } $rows[] = [$key['id'], $key['app_id'], $key['busiId'], $date, $total, $time, $time]; } $appIds = implode(',', array_unique($appIds)); $connection = Yii::$app->getDb(); $transaction = $connection->beginTransaction(); $columns = ['id', 'app_id', 'sms_business_id', 'stat_day', 'total', 'create_time', 'update_time']; $result = $connection->createCommand()->batchInsert(BusinessStat::tableName(), $columns, $rows)->execute(); if (!$result) { $this->stdout("应用ID为{$appIds}的应用系统业务维度统计失败!!!\r\n", Console::FG_RED); $this->_fileLogger->writeOne("应用ID为{$appIds}的应用系统业务维度统计失败!!!", Logger::LEVEL_INFO, 'console\\controllers\\SmsController::sms-batch-busi'); $transaction->rollBack(); exit(3); } $this->stdout("应用ID为{$appIds}的应用系统业务维度统计成功!!!\r\n", Console::FG_GREEN); $this->_fileLogger->writeOne("应用ID为{$appIds}的应用系统业务维度统计成功!!!", Logger::LEVEL_INFO, 'console\\controllers\\SmsController::sms-batch-busi'); $transaction->commit(); // 清除缓存 foreach ($keys as $key) { $redis->del($key['key']); } exit; } catch (Exception $ex) { $code = $ex->getCode(); if ($code == 23000) { $this->stdout("应用中存在已经被备份(主键重复)~~\r\n", Console::FG_RED); } else { $this->stdout("系统出错,请稍后重试~~\r\n", Console::FG_RED); } $transaction->rollBack(); $this->_fileLogger->writeOne($ex->getMessage(), Logger::LEVEL_ERROR, 'console\\controllers\\SmsController::sms-batch-daily'); // 1表示异常退出 exit(1); } }
/** * 根据短信服务配置短信验证 * * @param string $appid 应用系统ID * @param array $data 验证需要的参数 * * @return array [a,b] a代码 b具体信息 */ public function verifySetting($appid, $data, $isISystem = false) { // 获取文件缓存处理类 $cache = Yii::$app->getCache(); $settings = false; //$cache->get('sms:setting'); // 若缓存内容为空则查询数据库 if (!$settings || empty($settings)) { $appConfigs = SmsSetting::find()->asArray()->all(); if (arr_null($appConfigs)) { return [0, 'success']; } $settings = $this->buildAppIdArray($appConfigs); $cacheResult = $cache->set('sms:setting', $settings); if (!$cacheResult) { // TODO:: 缓存设置失败 } } if (!isset($settings[$appid])) { return [2202, 'error_appid_invalid']; } $setting = $settings[$appid]; if (!$isISystem) { // 若域名白名单不为空 if ($setting['domain_white_list']) { $domainWhiteList = json_decode($setting['domain_white_list'], true); // 若不在白名单内 if (!in_array($data['host'], $domainWhiteList)) { return [2007, 'error_domain_white_list']; } } // 若IP白名单不为空 if (isset($data['source']) || $setting['ip_white_list']) { $ipWhiteList = json_decode($setting['ip_white_list'], true); // 若不在白名单内 if (!in_array($data['source'], $ipWhiteList)) { return [2006, 'error_ip_white_list']; } } } $date = date('YmdH', time()); $key = 'SMS:MINUTE:' . $appid . ':' . $date; $minutes = date('i'); $failKey = 'SMS:STATUS:' . $appid . ':' . BaseSmsLog::STATUS_NOT_SEND . ':' . date('Ymd', time()); $userKey = 'SMS:RECUSER:'******':' . date('YmdH', time()); $userBusiKey = 'SMS:UBUSI:' . $appid . ':' . $data['busiID'] . ':' . date('Ymd', time()); $hour = date('H'); $redis = Yii::$app->redisCache->redis; // 同一手机相同内容短信量的限制 if ($setting['mobile_content_send_limit'] > 0) { $mobileConentKey = 'SMS:UCONTENT:' . $appid . ':' . date('Ymd', time()); $field = $data['mobile'] . ':' . md5($data['content']); $num = $redis->hget($mobileConentKey, $field); if ($num >= $setting['mobile_content_send_limit']) { return [2013, 'error_mobile_content_upperlimit']; } } // 用户业务每日接收上限控制 if ($data['ubusi_daily_upper_limit'] > 0) { $total = $redis->hget($userBusiKey, $data['mobile']); if ($total >= $data['ubusi_daily_upper_limit']) { return [2008, 'error_ubusi' . $data['busiID'] . '_upperlimit']; } } // 若应用每分钟发送上限大于0 if ($setting['app_minutely_send_limit'] > 0) { $total = $redis->hget($key, $minutes); if ($total > $setting['app_minutely_send_limit']) { return [2008, 'error_minutely_upperlimit']; } } // 若应用每小时发送上限大于0 if ($setting['app_hourly_send_limit'] > 0) { $result = $redis->hgetall($key); $total = count_sms_sum($result); if ($total >= $setting['app_hourly_send_limit']) { return [2003, 'error_hour_upperlimit']; } } // 失败小时上限 if ($setting['send_failed_hourly_limit']) { $total = $redis->hget($failKey, $hour); if ($total >= $setting['send_failed_hourly_limit']) { return [2010, 'error_hourly_fail_upperlimit']; } } // 失败天上限 if ($setting['send_failed_daily_limit']) { $result = $redis->hgetall($failKey); $total = count_sms_sum($result); if ($total >= $setting['send_failed_daily_limit']) { return [2009, 'error_daily_fail_upperlimit']; } } // 用户每小时发送上限 if ($setting['user_hourly_send_limit']) { $total = $redis->hget($userKey, $data['mobile']); if ($total >= $setting['user_hourly_send_limit']) { return [2011, 'error_hourly_user_upperlimit ']; } } return [0, $data]; }
/** * 批量插入 * * @param array $stat 字段值必须跟数据库中的字段顺序完全一样 * ~~ * [field1val,field2val,field3val...] * ~~ * @return int|false * @throws \yii\db\Exception */ public function batchInsertStat($stat) { // 若不是索引数组返回false if (arr_null($stat) || !ArrayHelper::isIndexed($stat)) { return false; } try { $db = self::getDb(); // 事物控制 $transaction = $db->beginTransaction(); // 已数组的形式返回表的字段(字段的默认顺序) $columns = $this->getColumns(); $result = self::find()->createCommand($db)->batchInsert(self::tableName(), $columns, $stat)->execute(); } catch (Exception $ex) { $transaction->rollBack(); return false; } if ($result) { $transaction->commit(); return $result; } else { $transaction->rollBack(); return false; } }