'ID', 'mall_id' => '商城id', 'province_id' => '省份编号', 'city_id' => '城市编号', 'pay_num' => '支付量', 'order_num' => '订单量', 'order_money' => '下单金额', 'pay_money' => '支付金额' ]; } public function behaviors() { return []; } /** * 区域订单统计 * * @param int mall_id 商城ID * @author hpei * @return array */ public static function getData($mall_id) { try { self::getDefaultRegion($mall_id); $redis = \Yii::$app->redis; $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::REGION_STATISTICS, 'mall_id_' . $mall_id); $regionStatistics = $redis->get($cacheKey); if (!$regionStatistics) { $regionStatistics = self::createCacheData($mall_id); self::setCache($mall_id, $regionStatistics); } else { $regionStatistics = json_decode($regionStatistics, true); } return self::setProvinceName($regionStatistics); } catch (\Exception $e) { Yii::error('读取地区统计缓存异常:' . $e->getMessage()); return empty(self::$provinceStatistics) ? [] : self::setProvinceName(self::$provinceStatistics); } } /** * 添加统计 * * @param array data [mall_id=>mall_id,city_id=>city_id,province_id=>province_id,order=>money|pay=>money] * @author hpei * @return bool */ public static function saveData($data) { try { $mall_id = $data['mall_id']; $city_id = $data['city_id']; $province_id = $data['province_id']; if (!$mall_id || !$city_id || !$province_id) { // self::$static_error = 'mall_id city_id province_id 为空'; // return false; return true; } self::getDefaultRegion($mall_id); $region = self::getOne([['=','mall_id', $mall_id], ['=', 'city_id', $city_id]]); $config = \Yii::$app->getComponents()['redis']; unset($config['class']); $redis = new Connection($config); $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::REGION_STATISTICS, 'mall_id_' . $mall_id); $regionStatistics = $redis->get($cacheKey); $order_money = (isset($data['order']) && !empty($data['order'])) ? $data['order'] : 0; $order_num = (isset($data['order']) && !empty($data['order'])) ? 1 : 0; $pay_money = (isset($data['pay']) && !empty($data['pay'])) ? $data['pay'] : 0; $pay_num = (isset($data['pay']) && !empty($data['pay'])) ? 1 : 0; if (!empty($region)) { $region->order_money += $order_money; $region->order_num += $order_num; $region->pay_money += $pay_money; $region->pay_num += $pay_num; $region->save(); } else { $regionData = array_column(self::$regionData, null, 'city_id'); $regionData[$city_id]['order_money'] = $order_money; $regionData[$city_id]['order_num'] = $order_num; $regionData[$city_id]['pay_money'] = $pay_money; $regionData[$city_id]['pay_num'] = $pay_num; Yii::$app->db->createCommand()->batchInsert(self::tableName(), ['mall_id', 'province_id', 'city_id', 'order_money', 'order_num', 'pay_money', 'pay_num'], $regionData)->execute(); } //有缓存在缓存上递增数据,没有缓存读取数据库 if (!empty($regionStatistics)) { $regionStatistics = json_decode($regionStatistics, true); $regionStatistics = array_column($regionStatistics, null, 'province_id'); if(!empty($regionStatistics[$province_id]['order_money'])){ $regionStatistics[$province_id]['order_money'] += $order_money; }else{ $regionStatistics[$province_id]['order_money'] = $order_money; } if(!empty($regionStatistics[$province_id]['order_num'])){ $regionStatistics[$province_id]['order_num'] += $order_num; }else{ $regionStatistics[$province_id]['order_num'] = $order_num; } if(!empty($regionStatistics[$province_id]['pay_money'])){ $regionStatistics[$province_id]['pay_money'] += $pay_money; }else{ $regionStatistics[$province_id]['pay_money'] = $pay_money; } if(!empty($regionStatistics[$province_id]['pay_num'])){ $regionStatistics[$province_id]['pay_num'] += $pay_num; }else{ $regionStatistics[$province_id]['pay_num'] = $pay_num; } } else { $regionStatistics = self::getProvinceStatistics($mall_id); } self::setCache($mall_id, array_values($regionStatistics)); return true; } catch (\Exception $e) { self::$static_error = $e->getMessage().$e->getFile().$e->getLine(); return false; } } /** * 设置缓存 * * @param int mall_id * @param array|string|int $regionStatistics * @return bool */ public static function setCache($mall_id, $regionStatistics) { $config = \Yii::$app->getComponents()['redis']; unset($config['class']); $redis = new Connection($config); try { $cacheKey = RedisKeyEnum::suffix(RedisKeyEnum::REGION_STATISTICS, 'mall_id_' . $mall_id); $redis->del($cacheKey); if (is_array($regionStatistics)) { $redis->set($cacheKey, json_encode($regionStatistics, JSON_UNESCAPED_UNICODE)); } else { } $redis->close(); } catch (\Exception $e) { Yii::error('设置区域统计缓存异常:'.$e->getMessage()); $redis->close(); } } /** * 生成缓存数据 如果数据库没有数据则入库 */ public static function createCacheData($mall_id) { try { $regionStatistics = self::find() ->where(['mall_id' => $mall_id]) ->andWhere(['in', 'province_id', self::$provinceIds]) ->select(['province_id', 'pay_money'])->groupBy('province_id')->asArray()->all(); //如果不存在给默认值,并把默认值入库 if (empty($regionStatistics)) { $regionStatistics = self::$provinceStatistics; Yii::$app->db->createCommand()->batchInsert(self::tableName(), ['mall_id', 'province_id', 'city_id', 'order_money', 'order_num', 'pay_money', 'pay_num'], self::$regionData)->execute(); } return $regionStatistics; } catch (\Exception $e) { throw new \Exception('地区缓存。生成缓存数据' . $e->getMessage() . ',行数:' . $e->getLine()); } } /** * 设置默认区域 * * @param array regionData 入库的数据 * @param array provinceIds 省份ID * @param array provinceStatistics 展示的默认数据 * @return void */ public static function getDefaultRegion($mall_id) { $regionList = Region::find() ->where(['level' => [1, 2]]) ->select(['name', 'id', 'level', 'parent_id', new Expression('0 as pay_money')]) ->asArray()->all(); $name = []; $regionData = []; $provinceIds = []; $provinceStatistics = []; array_walk($regionList, function($region) use(&$provinceIds, &$provinceStatistics, &$regionData, &$name, $mall_id) { if ($region['level'] == 2) { $regionData[] = [ 'mall_id' => $mall_id, 'province_id' => $region['parent_id'], 'city_id' => $region['id'], 'order_money' => 0, 'order_num' => 0, 'pay_money' => 0, 'pay_num' => 0]; } if ($region['level'] == 1) { $provinceIds[] = $region['id']; $name[$region['id']] = $region['name']; $region['province_id'] = $region['id']; unset($region['level'], $region['parent_id'], $region['name'], $region['id']); $provinceStatistics[] = $region; } }); self::$provinceName = $name; self::$regionData = $regionData; self::$provinceIds = $provinceIds; self::$provinceStatistics = $provinceStatistics; } /** * 统计数据添加省份名称 * * @param array provinceStatistics */ public static function setProvinceName($provinceStatistics) { $provinceName = self::$provinceName; array_walk($provinceStatistics, function(&$region) use($provinceName) { $region['name'] = $provinceName[$region['province_id']]??''; }); return $provinceStatistics; } /** * */ public static function getProvinceStatistics($mall_id) { return self::find()->where(['mall_id' => $mall_id]) ->select(['province_id', 'sum(pay_money) pay_money']) ->groupBy('province_id')->asArray()->all(); } /** * 重新设置缓存 */ public static function resetCache($mall_id) { try { self::getDefaultRegion($mall_id); $regionStatistics = self::createCacheData($mall_id); self::setCache($mall_id, $regionStatistics); } catch (\Exception $e) { throw new \Exception($e->getMessage()); } } }