| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- <?php
- namespace common\models\statistics;
- use common\models\base\BaseActiveRecord;
- use common\enums\StatusEnum;
- use common\enums\RedisKeyEnum;
- use common\models\user\UserLevel;
- use Yii;
- use yii\redis\Connection;
- /**
- *
- * @property int $mall_id
- * @property int $browse_num
- * @property int $follow_num
- * @property json $upgrade_level
- * @property int $date
- */
- class GlobalStatistics extends BaseActiveRecord
- {
- private static $fields = ['browse_num' => 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());
- }
- }
- }
|