bnbwebexpertise / laravel-sequence
Laravel 包用于处理模型序列生成(无间隔)
0.0.8
2019-03-05 05:55 UTC
Requires
- php: >=5.6.4
- laravel/framework: >=5.4.0
README
本包提供与 Laravel 模型中无间隔和有序整数序列一起工作的辅助工具。
它旨在帮助生成“管理序列”,其中记录之间不应有缺失值(发票等)。
警告 这是一个 beta 版本(原型)。这尚未准备好用于生产,因此您应自行承担风险。
安装
将服务提供程序添加到您的配置
'providers' => [ // ... Bnb\Laravel\Sequence\SequenceServiceProvider::class, // ... ],
配置
您可以通过发布配置文件来自定义此包的行为
php artisan vendor:publish --provider='Bnb\Laravel\Sequence\SequenceServiceProvider'
您可以通过在 .env
文件中指定这些键来自定义值而不发布
SEQUENCE_START=123 # defaults to 1
SEQUENCE_QUEUE_CONNECTION=database # defaults to default
SEQUENCE_QUEUE_NAME=sequence # defaults to default
SEQUENCE_AUTO_DISPATCH=false # defaults to true
为了避免在生成序列号时出现并发问题,队列工作进程数量应设置为 1。建议使用专用队列(和工作进程)。
将序列添加到模型
序列列应使用以下配置在您的迁移中生成
$table->unsignedInteger('sequence_name')->nullable()->unique();
要使用序列,必须通过 Bnb\Laravel\Sequence\HasSequence
特性增强您的模型类。
您的模型类的 sequences
数组属性必须包含序列名称列表
public $sequences = ['my_sequence'];
某些序列属性可以通过在模型类中指定方法来覆盖(其中 MySequence
是您序列的 PascalCase 名称)
- 序列起始值(每个序列)使用
getMySequenceStartValue() : int
- 序列格式(每个序列)使用
formatMySequenceSequence($next, $last) : int
- 序列生成授权(每个序列)使用
canGenerateMySequenceSequence() : bool
- 序列间隔填充模式(每个序列)
isMySequenceGapFilling() : bool
- 序列生成队列连接(对于模型类)
getSequenceConnection() : string
- 序列生成队列名称(对于模型类)
getSequenceQueue() : string
- 序列自动派发激活(对于模型类)
isSequenceAutoDispatch() : bool
示例
use Bnb\Laravel\Sequence\HasSequence;
use Illuminate\Database\Eloquent\Model;
/**
* MyModel model uses a sequence named
*/
class MyModel extends Model
{
use HasSequence;
const SEQ_INVOICE_NUMBER_START = 0;
public $timestamps = false;
protected $fillable = ['active'];
protected $sequences = ['invoice_number'];
/**
* Assume the sequence can only be generated if active is true
*/
protected function canGenerateReadOnlySequence()
{
return $this->active;
}
/**
* The sequence default value must match the format
*/
protected function getInvoiceNumberStartValue()
{
return sprintf('%1$04d%2$06d', date('Y'), static::SEQ_INVOICE_NUMBER_START);
}
/**
* Format the sequence number with current Year that resets its counter to 0 on year change
*/
protected function formatInvoiceNumberSequence($next, $last)
{
$newYear = date('Y');
$newCounter = substr($next, 4);
if ($last) {
$lastYear = substr($last, 0, 4);
if ($lastYear < $newYear) {
$newCounter = static::SEQ_INVOICE_NUMBER_START;
}
}
return sprintf('%1$04d%2$06d', $newYear, $newCounter);
}
/**
* If `true`, the first number available is used, ie. the lowest number available, greater or equal to start number, including gaps caused by deletion (soft-delete included)
* If `false` (default value), the next number will always be the last number used + 1 or the first number of the sequence when nothing pre-exists
*/
protected function isSequenceGapFilling()
{
return false;
}
}
序列生成事件
当生成序列号时,会抛出一个模型事件以运行自定义任务。您可以使用 sequenceGenerated($sequenceName, $callback)
方法(例如在服务提供程序的 boot 方法中)来监听序列事件
MyModel::sequenceGenerated('invoice_number', function ($model) {
Mail::to($model->recipient_email)->send(new InvoiceGenerated($model));
});
计划生成
您可以在控制台内核中计划 Bnb\Laravel\Sequence\Console\Commands\UpdateSequence
,以所需频率异步生成缺失的序列号。
protected function schedule(Schedule $schedule)
{
$schedule->command('sequence:update')
->hourly();
}
当使用自动派发模式时,可能不需要此操作,但可以用作安全后备。