You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yanzong/app/common/model/Region.php

290 lines
8.8 KiB

<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use app\common\library\helper;
use cores\BaseModel;
use think\facade\Cache;
/**
* 地区模型
* Class Region
* @package app\common\model
*/
class Region extends BaseModel
{
// 定义表名
protected $name = 'region';
// 定义主键
protected $pk = 'id';
protected $createTime = false;
protected $updateTime = false;
/**
* 类型自动转换
* @var array
*/
protected $type = [
'id' => 'integer',
'pid' => 'integer',
'level' => 'integer',
];
// 当前数据版本号
private static string $version = '1.0.3';
public static function init()
{
// self::$storeId = 0;
// app()->request->setStoreId(0);
}
/**
* 根据ID获取地区名称
* @param int $id
* @return mixed|string
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getNameById(int $id = 0)
{
if ($id == 0) {
return '其他';
}
$data = self::getCacheAll();
return isset($data[$id]) ? $data[$id]['name'] : '其他';
}
/**
* 根据名称获取地区ID
* @param string $name
* @param int $level
* @param int $pid
* @return int|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getIdByName(string $name, int $level = 0, int $pid = 0)
{
$data = self::getCacheAll();
foreach ($data as $item) {
if ($item['name'] == $name && $item['level'] == $level && $item['pid'] == $pid) {
return $item['id'];
}
}
return 0;
}
/**
* 获取所有地区(树状结构)
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getCacheTree(): array
{
return static::getCacheData('tree');
}
/**
* 获取所有地区列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getCacheAll(): array
{
return static::getCacheData('all');
}
/**
* 获取所有地区的总数
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getCacheCounts(): array
{
return static::getCacheData('counts');
}
/**
* 获取缓存中的数据(存入静态变量)
* @param null $item
* @return array|mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private static function getCacheData($item = null)
{
static $cacheData = [];
if (empty($cacheData)) {
$static = new static;
$cacheData = $static->regionCache();
}
if (is_null($item)) {
return $cacheData;
}
return $cacheData[$item];
}
public function getNewTreeList()
{
$treeList = Cache::get('region2');
if ($treeList) {
return $treeList;
}
$allList = self::withoutGlobalScope()
->field('id, pid, name, level')
->select()
->toArray();
$treeList = [];
$i = 0;
foreach ($allList as $pKey => $province) {
if ($province['level'] == 1) { // 省份
$treeList[$i] = $province;
unset($allList[$pKey]);
$j = 0;
foreach ($allList as $cKey => $city) {
if ($city['level'] == 2 && $city['pid'] == $province['id']) { // 城市
$treeList[$i]['children'][$j] = $city;
unset($allList[$cKey]);
$m = 0;
foreach ($allList as $rKey => $region) {
if ($region['level'] == 3 && $region['pid'] == $city['id']) { // 地区
$treeList[$i]['children'][$j]['children'][$m] = $region;
unset($allList[$rKey]);
$m++;
}
}
$j++;
}
}
$i++;
}
}
Cache::tag('cache')->set('region2', $treeList);
return $treeList;
}
/**
* 获取地区缓存
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function regionCache(): array
{
// 缓存的数据
$complete = Cache::get('region');
// 如果存在缓存则返回缓存的数据,否则从数据库中查询
// 条件1: 获取缓存数据
// 条件2: 数据版本号要与当前一致
if (
!empty($complete)
&& isset($complete['version'])
&& $complete['version'] == self::$version
) {
return $complete;
}
// 所有地区
$allList = $tempList = $this->getAllList();
// 已完成的数据
$complete = [
'all' => $allList,
'tree' => $this->getTreeList($allList),
'counts' => $this->getCount($allList),
'version' => self::$version,
];
// 写入缓存
Cache::tag('cache')->set('region', $complete);
return $complete;
}
/**
* 地区总数
* @param $allList
* @return array
*/
private static function getCount($allList): array
{
$counts = [
'total' => count($allList),
'province' => 0,
'city' => 0,
'region' => 0,
];
$level = [1 => 'province', 2 => 'city', 3 => 'region'];
foreach ($allList as $item) {
$counts[$level[$item['level']]]++;
}
return $counts;
}
/**
* 格式化为树状格式
* @param $allList
* @return array
*/
private function getTreeList($allList): array
{
$treeList = [];
foreach ($allList as $pKey => $province) {
if ($province['level'] == 1) { // 省份
$treeList[$province['id']] = $province;
unset($allList[$pKey]);
foreach ($allList as $cKey => $city) {
if ($city['level'] == 2 && $city['pid'] == $province['id']) { // 城市
$treeList[$province['id']]['city'][$city['id']] = $city;
unset($allList[$cKey]);
foreach ($allList as $rKey => $region) {
if ($region['level'] == 3 && $region['pid'] == $city['id']) { // 地区
$treeList[$province['id']]['city'][$city['id']]['region'][$region['id']] = $region;
unset($allList[$rKey]);
}
}
}
}
}
}
return $treeList;
}
/**
* 从数据库中获取所有地区
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getAllList(): array
{
$list = self::withoutGlobalScope()
->field('id, pid, name, level')
->select()
->toArray();
return helper::arrayColumn2Key($list, 'id');
}
}