0, 'follow_num' => 0, 'visitor_num' => 0, 'register_num' => 0,'upgrade_level' => '{}']; /** * {@inheritdoc} */ public static function tableName() { return '{{%global_statistics}}'; } /** * {@inheritdoc} */ public function rules() { return [ [['mall_id', 'browse_num', 'visitor_num', 'follow_num', 'register_num', 'date'], 'required'], [['mall_id', 'browse_num', 'visitor_num', 'follow_num', 'register_num', 'goods_num', 'date'], 'integer'], [['upgrade_level'], 'safe'], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'mall_id' => '商城id', 'browse_num' => '浏览量', 'follow_num' => '关注数', 'visitor_num' => '访客量', 'register_num' => '注册数', 'goods_num' => '商品数量', 'upgrade_level' => '用户等级', 'date' => '日期', ]; } public function behaviors() { return []; } /** * 读取数据 * * @param int $mall_id * @author hpei * @return array */ public static function getData($mall_id) { try { $redis = \Yii::$app->redis; $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::GLOBAL_STATISTICS, 'mall_id_'. $mall_id); $globalStatistics = $redis->hgetall($cacheKey); $levels = UserLevel::getListIndexByLevelColumn($mall_id); if (empty($globalStatistics)) { $globalStatistics = self::createCacheData($mall_id, $levels); self::setCache($mall_id, $globalStatistics); } else { $num = 0; $fields = []; $values = []; foreach ($globalStatistics as $val) { if ($num % 2 === 0) { $fields[] = $val; } else { $values[] = $val; } $num++; } $globalStatistics = array_combine($fields, $values); $globalStatistics['yesterday_upgrade_level'] = json_decode($globalStatistics['yesterday_upgrade_level'], true); $globalStatistics['today_upgrade_level'] = json_decode($globalStatistics['today_upgrade_level'], true); } return self::getShowData($globalStatistics, $levels); } catch (\Exception $e) { Yii::error('读取全局统计缓存异常:' . $e->getMessage()); if (isset($defaultData) && isset($values)) { return self::getShowData($defaultData, $levels); } throw new \Exception($e->getMessage() . ',行数:' . $e->getLine()); } } /** * 保存数据 * * @param int $mall_id * @param array $data [browse_num=>browse_num|follow_num=>follow_num|register_num=>register_num|upgrade_level=>[level=>num]] * @author hpei * @return bool */ public static function saveData($mall_id, $data) { try { $levels = UserLevel::getListIndexByLevelColumn($mall_id); $defaultData = self::getDefaultStatistics($levels); $date = date('Ymd'); $globalMdl = self::find()->where(['mall_id' => $mall_id, 'date' => $date])->one(); if (empty($globalMdl)) { $globalMdl = new self(); $globalMdl->mall_id = $mall_id; $globalMdl->date = $date; $globalMdl->load($defaultData, ''); } //循环赋值 foreach ($data as $key => $val) { if ($key == 'upgrade_level' && isset($data['upgrade_level']) && !empty($data['upgrade_level'])) { //循环默认等级,即使当天新增了等级,也会设置数量为0 foreach ($defaultData['upgrade_level'] as $level => $num) { if (isset($data['upgrade_level'][$level])) { if (!isset($globalMdl->upgrade_level[$level])) { $defaultData['upgrade_level'][$level] = $data['upgrade_level'][$level]; } else { $defaultData['upgrade_level'][$level] = $globalMdl->upgrade_level[$level] + $data['upgrade_level'][$level]; } } } $globalMdl->upgrade_level = $defaultData['upgrade_level']; } else { $globalMdl->{$key} += $val; } } if (!$globalMdl->save()) { self::$static_error = $globalMdl->getErrorMessage(); return false; } $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::GLOBAL_STATISTICS, 'mall_id_'. $mall_id); $config = \Yii::$app->getComponents()['redis']; unset($config['class']); $redis = new Connection($config); //是否要设置昨日数据缓存 $isSetCache = true; if (!$redis->hget($cacheKey, 'yesterday_register_num') || !$redis->hget($cacheKey, 'upgrade_level') || !$redis->hget($cacheKey, 'follow_num')) { $isSetCache = false; } $isSetCache = $redis->hget($cacheKey, 'yesterday_register_num') ? true : false; //组装缓存数据 $globalStatistics = []; foreach ($globalMdl as $field => $value) { if (isset(self::$fields[$field])) { $globalStatistics['today_' . $field] = $value; if ($isSetCache === false) { $globalStatistics['yesterday_' . $field] = $defaultData[$field]; } } } $user_num = $redis->hget($cacheKey, 'user_num'); $globalStatistics['user_num'] = $user_num ?? 0; if (isset($globalMdl->register_num) && $globalMdl->register_num != 0) { if ($user_num) { $globalStatistics['user_num'] += 1; } else { $globalStatistics['user_num'] = self::find()->where(['mall_id' => $mall_id])->sum('register_num') ?? 0; } } self::setCache($mall_id, $globalStatistics); return true; } catch (\Exception $e) { self::$static_error = '设置全局统计错误,' . $e->getMessage() . ',行数' . $e->getLine(); return false; } } /** * 设置缓存 * * @param int $mall_id * @param array $globalStatistics 统计数据 * @author hpei * @return void */ public static function setCache($mall_id, $globalStatistics) { $config = \Yii::$app->getComponents()['redis']; unset($config['class']); $redis = new Connection($config); $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::GLOBAL_STATISTICS, 'mall_id_'. $mall_id); try { //hmset foreach ($globalStatistics as $field => $value) { $value = is_array($value) ? json_encode($value, JSON_UNESCAPED_UNICODE) : $value; $redis->hset($cacheKey, $field, $value); } $redis->expire($cacheKey, strtotime("+1 day 0:0:0") - time()); $redis->close(); } catch (\Exception $e) { Yii::error('设置全局统计缓存异常:'.$e->getMessage()); $redis->close(); } } /** * 生成缓存数据 如果数据库没有数据则入库 * * @param int $mall_id * @param array $level common\models\user\UserLevel * @return array */ public static function createCacheData($mall_id, $levels) { try { $defaultData = self::getDefaultStatistics($levels); $yesterday = date('Ymd', strtotime("-1 day")); $today = date('Ymd'); $globalMdl = self::find()->select(['id', 'browse_num', 'visitor_num', 'follow_num', 'register_num', 'goods_num', 'upgrade_level', 'date']) ->where(['mall_id' => $mall_id])->andWhere(['in', 'date', [$yesterday, $today]])->indexBy('date')->limit(2)->all(); $globalStatistics = []; $insertData = $defaultData; if (!isset($globalMdl[$yesterday])) { $yesterdayModel = new self(); $yesterdayModel->loadDefaultValues(); $insertData['date'] = $yesterday; $insertData['mall_id'] = $mall_id; $yesterdayModel->load($insertData, ''); $yesterdayModel->save(); $yesterdayStatistics = $defaultData; } else { $yesterdayStatistics = $globalMdl[$yesterday]; } if (!isset($globalMdl[$today])) { $todayModel = new self(); $todayModel->loadDefaultValues(); $insertData['date'] = $today; $insertData['mall_id'] = $mall_id; $todayModel->load($insertData, ''); $todayModel->save(); $todayStatistics = $defaultData; } else { $todayStatistics = $globalMdl[$today]; } array_walk($defaultData, function($defaultValue, $field) use($levels, $todayStatistics, $yesterdayStatistics, &$globalStatistics) { if ($field == 'upgrade_level') { $globalStatistics['today_upgrade_level'] = self::removeLevel($todayStatistics['upgrade_level'], $levels); $globalStatistics['yesterday_upgrade_level'] = self::removeLevel($yesterdayStatistics['upgrade_level'], $levels); } else { $globalStatistics['today_' . $field] = $todayStatistics[$field]; $globalStatistics['yesterday_' . $field] = $yesterdayStatistics[$field]; } }); $user_num = self::find()->where(['mall_id' => $mall_id])->sum('register_num'); $globalStatistics['user_num'] = $user_num; $totalData = self::find()->where(['mall_id' => $mall_id]) ->select(['sum(browse_num) total_browse_num', 'sum(visitor_num) total_visitor_num', 'sum(follow_num) total_follow_num'])->asArray()->one(); if (empty($totalData)) { $globalStatistics['total_browse_num'] = 0; $globalStatistics['total_visitor_num'] = 0; $globalStatistics['total_follow_num'] = 0; } else { $globalStatistics['total_browse_num'] = $totalData['total_browse_num']; $globalStatistics['total_visitor_num'] = $totalData['total_visitor_num']; $globalStatistics['total_follow_num'] = $totalData['total_follow_num']; } return $globalStatistics; } catch (\Exception $e) { throw new \Exception('全局缓存。生成缓存数据' . $e->getMessage() . ',行数:' . $e->getLine()); } } /** * 默认数据 * * @param int mall_id * @param array $levels common\models\user\UserLevel * @param bool $day_data 是否分别设置昨天,今天数据 * @author hpei * @return array */ public static function getDefaultStatistics($levels, $day_data = false) { $upgrade_level = []; foreach ($levels as $level => $levelName) { $upgrade_level[$level] = 0; } $defaultData = self::$fields; $defaultData['upgrade_level'] = $upgrade_level; return $defaultData; } /** * 排除写入统计表后删除的等级 * * @param array $upgradeLevel 要筛选的等级 [level=>level_num] * @param array $levels common\models\user\UserLevel * @author hpei * @return array */ public static function removeLevel($upgradeLevel, $levels) { $newUpgradeLevel = []; foreach ($levels as $level => $levelName) { if (isset($upgradeLevel[$level])) { $newUpgradeLevel[$level] = $upgradeLevel[$level]; } else { $newUpgradeLevel[$level] = 0; } } ksort($newUpgradeLevel); return $newUpgradeLevel; } /** * 添加注册用户数量 * * @param int $mall_id */ public static function increaseRegisterNum($mall_id) { try { $date = date('Ymd'); $globalMdl = self::find()->where(['mall_id' => $mall_id, 'date' => $date])->one(); if (empty($globalMdl)) { $globalMdl = new self(); $levels = UserLevel::getListIndexByLevelColumn($mall_id); $defaultData = self::getDefaultStatistics($levels); $defaultData['mall_id'] = $mall_id; $defaultData['date'] = $date; $globalMdl->load($defaultData, ''); $globalMdl->register_num = 1; } else { $globalMdl->register_num += 1; } $globalMdl->save(); return true; } catch (\Exception $e) { self::$static_error = $e->getMessage(); return false; } } /** * 发布商品 */ public static function publishGoods($mall_id) { try { $date = date('Ymd'); $globalMdl = self::find()->select(['goods_num'])->where(['mall_id' => $mall_id, 'date' => $date])->one(); if (empty($globalMdl)) { $globalMdl = new self(); $levels = UserLevel::getListIndexByLevelColumn($mall_id); $defaultData = self::getDefaultStatistics($levels); $defaultData['mall_id'] = $mall_id; $defaultData['date'] = $date; $globalMdl->load($defaultData, ''); $globalMdl->goods_num = 1; } else{ $globalMdl->goods_num += 1; } if (!$globalMdl->save()) { self::$static_error = $globalMdl->getErrorMessage(); return false; } return true; } catch (\Exception $e) { self::$static_error = $e->getMessage(); return true; } } /** * 返回首页最终展示的数据 */ public static function getShowData($globalStatistics, $levels) { $list = []; foreach ($levels as $level => $levelName) { $proportion = 100; if(!empty($globalStatistics['yesterday_upgrade_level'][$level]) && !empty($globalStatistics['today_upgrade_level'][$level])){ $proportion = ($globalStatistics['today_upgrade_level'][$level] - $globalStatistics['yesterday_upgrade_level'][$level])/$globalStatistics['yesterday_upgrade_level'][$level] * 100; }else{ if(empty($globalStatistics['today_upgrade_level'][$level])) $proportion = 0; if(empty($globalStatistics['yesterday_upgrade_level'][$level])) $proportion = 0; } $list[] = ['id' => $level, 'name' => $levelName, 'today_num' => $globalStatistics['today_upgrade_level'][$level], 'yesterday_num' => $globalStatistics['yesterday_upgrade_level'][$level], 'proportion' =>$proportion ]; } unset($globalStatistics['yesterday_upgrade_level'],$globalStatistics['today_upgrade_level']); $globalStatistics['level_list'] = $list; return $globalStatistics; } /** * 重新生成缓存 */ public static function resetCache($mall_id) { try { $levels = UserLevel::getListIndexByLevelColumn($mall_id); $globalStatistics = self::createCacheData($mall_id, $levels); self::setCache($mall_id, $globalStatistics); } catch (\Exception $e) { throw new \Exception($e->getMessage()); } } }