devront-it / laravel-advanced-statistics
Laravel 统计 API
Requires
- php: ^8.2
- laravel/framework: ^9.0|^10.0|^11.0
- spatie/laravel-package-tools: ^1.15.0
Requires (Dev)
- nette/php-generator: ^4.0
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-arch: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
README
每次开始一个新项目时,我都讨厌考虑统计数据。这就是为什么在我的应用程序中,仪表板是最后填满的东西。我需要的是一个简单的 API,我可以定义、增加、计数和清理各种目的的统计数据。这就是结果。
主要功能
- 将统计数据定义为简单的 PHP 类
- 定义您希望保留每日和月度统计数据的时长
- 清理:每日统计数据将自动累积到月度统计数据中
- 使用魔法方法(包含 IDE 辅助生成器)简单地查询您的统计数据
- 计算平均值
工作原理
这个包不仅仅依赖于计数模型。例如:我不想知道我的数据库中有多少订单。你真的不需要一个包来做这个。我需要知道的是
- 我来自国家 x 的订单有多少?
- 我的履行提供商平均需要多长时间来履行订单?
- 两者的组合:与西班牙的履行提供商相比,在 11 月高峰时段,我的德国履行提供商平均需要多长时间来履行订单?
- 这个列表可以继续...
其中一些查询可能非常昂贵。这就是为什么这个包将所有内容存储在自己的数据库表中。它将每日和月度统计数据分开,并在 x 天后自动合并,这可以针对每个统计量进行配置。它还根据预定义的时间段清理统计数据。
也许有一天我会制作一些利用此包的 Livewire 组件来提供 UI。
安装
使用 composer 安装包
composer require devront-it/laravel-advanced-statistics
使用以下命令发布和运行迁移
php artisan vendor:publish --tag="advanced-statistics-migrations"
php artisan migrate
默认情况下,表名将是 'advanced_statistics'。如果与其他表冲突,只需将此添加到您的 ApplicationServiceProvider 中
statistics()->withTablePrefix('custom_prefix_'); // Will result in 'custom_prefix_statistics' table // or app(Devront\AdvancedStatistics\AdvancedStatistics::class)->withTablePrefix(...)
不需要配置文件。
调度程序
此包附带一个作业,应在每天 00:00 运行。
// Inside your App\Console\Kernel.php use \Devront\AdvancedStatistics\Jobs\CalculateStatisticsJob; $schedule->job(CalculateStatisticsJob::class) ->dailyAt('0:0') ->onOneServer();
用法
首先,您需要为您的统计数据定义一个类
use Devront\AdvancedStatistics\Attributes\AdvancedStatisticsAttribute; use Devront\AdvancedStatistics\Statistics; #[AdvancedStatisticsAttribute] class OrderStatistics extends Statistics { }
对于简单的统计数据,您只想增加一个值,这已经足够了。但您也可以定义一些参数/元数据。
use Devront\AdvancedStatistics\Attributes\AdvancedStatisticsAttribute; use Devront\AdvancedStatistics\Attributes\Param; use Devront\AdvancedStatistics\Statistics; #[AdvancedStatisticsAttribute] class OrderStatistics extends Statistics { #[Param] protected string $country_code; #[Param] protected string $payment_method; }
您可以将一些参数传递给 AdvancedStatisticsAttribute
- type:您统计数据的唯一类型。默认为您的类名,在本例中为
<namespace>\OrderStatistics
- keepDailyStatisticsForDays:在将每日统计数据累积并存储在月度统计数据中之前,您希望保留每日统计数据的天数。默认为 90 天。
- keepMonthlyStatisticsForMonths:在删除月度统计数据之前,您希望保留月度统计数据的时间。默认为 24 个月。
use Devront\AdvancedStatistics\Attributes\AdvancedStatisticsAttribute; use Devront\AdvancedStatistics\Attributes\Param; use Devront\AdvancedStatistics\Statistics; #[AdvancedStatisticsAttribute( type: 'orders', keepDailyStatisticsForDays: 90, keepMonthlyStatisticsForMonths: 24 )] class OrderStatistics extends Statistics { #[Param] protected string $country_code; #[Param] protected string $payment_method; }
更新和检索值:->get()
和 ->hit()
现在您可以开始计数和检索统计数据。当编写查询时,您可以使用 hit()
(增加值)或 get()
(检索值)来结束查询。
可用于链式查询的方法
有关自定义参数行为的说明
// hit() without forCountryCode() will result in incrementing the statistics for orders with country_code=null (new OrderStatistics) ->for($user) ->hit();
// get() without forCountryCode() will result in counting all orders together, no matter what value country_code has (new OrderStatistics) ->for($user) ->get();
// If you want to count all orders where country_code is null, you need to explicitly write it down: (new OrderStatistics) ->for($user) ->forCountryCode(null) ->get();
平均值
统计类配置
use Devront\AdvancedStatistics\Attributes\Avg; #[AdvancedStatisticsAttribute] class OrderStatistics extends Statistics { // ...other params /** * How many hours passed between ordered and shipped */ #[Avg] protected float $time_to_fulfill; }
用法
(new OrderStatistics) ->for($user) ->timeToFulfill(2.5) // ... maybe other params ->hit(); (new OrderStatistics) ->for($user) ->timeToFulfill(4) // ... maybe other params ->hit(); // Get the average, returns 3.25 $average = (new OrderStatistics) ->for($user) ->from(now()->startOfYear()) // ... maybe other params ->getAverageTimeToFulfill(); // Takes decimal places as argument, default = 2 // ->getAverageTimeToFulfill(1); would return the value rounded to one place: 3.3
注意:如果您的统计类包含 #[Avg]
值,您必须在 ->hit()
统计数据之前始终提供它。
传递 null
到平均值参数
平均值参数(本例中的 timeToFulfill)也可以为 null
。如果您传递 null,则平均值将保持不变。这可以很有用,如果您想增加统计数据,但出于某种原因,您有一个非常不切实际的价值,并且不希望它破坏您的平均统计数据。
例如,您可能有一个非常旧的测试订单,您已经忘记了。有一天,您决定发货以将其丢弃。现在 timeToFulfill 将非常大,可能会破坏您的平均统计数据。因此,您可以定义一个阈值,如果超过了这个阈值,就将 timeToFulfill 传递为 null。
top() 方法
top()
方法提供了一种灵活且强大的方式来从负载(您的自定义参数)中检索基于指定字段的顶级记录。此功能允许您根据单个字段或多个字段的组合对数据进行分组和聚合。
用法
按单个字段(sku)分组的 Top 5 产品
// Get the top 5 best-selling products $top_selling_5_products = (new YourItemStats) ->for($user) // ... your other filters like from() and to() ->top('sku', 5); $top_selling_5_products->first()->sku; $top_selling_5_products->first()->total_value;
按多个字段分组的 Top 10 结果
$top_results = (new YourCustomStats) ->for($user) // ... your other filters like from() and to() ->top(['param1', 'param2'], 10); $top_results->first()->param1; $top_results->first()->param2; $top_results->first()->total_value;
返回值
此方法返回一个顶级记录集合,按指定期间的聚合值降序排序。结果中的每个条目将包括在 fields
参数中定义的字段,以及表示该组的计算指标的聚合 total_value
。
IDE 自动完成魔法方法
此包附带一个命令,用于生成一个 _ide_helper_statistics.php 文件,以在链式调用魔法方法(如上面的 forCountryCode())时提供更好的自动完成。
php artisan ide-helper:advanced-statistics
配置
使用 uuids
如果您正在使用 uuids,请确保在运行迁移之前,将其放在您的 AppServiceProvider 的 boot 方法中。
statistics()->useUuids();
这将设置主键和形态关系中的 owner_id 为 uuid。
扩展默认的 Statistic 模型
如果您想扩展默认的 Statistic 模型,请在您的 AppServiceProvider 的 boot 方法中指定您的模型。
statistics()->useModel(YourCustomModel::class);
class YourCustomModel extends \Devront\AdvancedStatistics\Models\Statistic { ... }
变更日志
这是初始版本。
贡献
欢迎贡献。
安全漏洞
如果您发现安全漏洞,请告诉我。
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件。