Laravel - 生成唯一的订单号
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49446329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel - generate unique order number
提问by Rainier Laan
I'm currently trying to generate a unique order number when the user reaches the create method. The order numbers are generated like this in the seed and need to look like this as well
我目前正在尝试在用户到达 create 方法时生成一个唯一的订单号。订单号在种子中是这样生成的,也需要看起来像这样
Seed
种子
foreach(range(1,25) as $index)
{
DB::table('orders')->insert([
'user_id' => rand(1,25),
'order_nr' => '#' . sprintf("%08d", $index),
'price_sum' => $faker->randomNumber($nbDigits = 4, $strict = false) . '.' . $faker->randomNumber($nbDigits = 2, $strict = false),
'status' => $faker->randomElement(['paid', 'pending', 'failed']),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
The order numbers look like this #00000001
or #00000002
. Now when the user reaches the create method in my controller a new unique order number in this sequence needs to be created. How can I achieve that? The controller currently looks like this:
订单号看起来像这样#00000001
或#00000002
。现在,当用户到达我的控制器中的 create 方法时,需要在此序列中创建一个新的唯一订单号。我怎样才能做到这一点?控制器目前看起来像这样:
public function create()
{
$order = new Order;
$order->user_id = Auth()->id();
$order->order_nr =
dd($order);
return view('steps.order');
}
It needs to check the latest order number and create one with +1 on that order number. Say for instance there are 25 orders and the last one is #00000025 the one that needs to be created next needs to be #00000026. How can I achieve that?
它需要检查最新的订单号并在该订单号上创建一个带有 +1 的订单号。比如说有25个订单,最后一个是#00000025,接下来需要创建的订单是#00000026。我怎样才能做到这一点?
回答by KalyanLahkar
Try doing as following
尝试执行以下操作
$order = new Order;
$order->user_id = Auth()->id();
$latestOrder = App\Order::orderBy('created_at','DESC')->first();
$order->order_nr = '#'.str_pad($latestOrder->id + 1, 8, "0", STR_PAD_LEFT);
$order->save();
Here I am assuming that the id is auto-incrementing. See the str_padmethod for more details
这里我假设 id 是自动递增的。有关更多详细信息,请参阅str_pad方法
回答by Adam
Use the auto column id value of your rows to generate the order number. However, do not create an extra column for your order number, because this would give you an unnormalized DB, since the order-column is completely dependent of the id column.
使用行的自动列 id 值生成订单号。但是,不要为您的订单号创建额外的列,因为这会给您一个非规范化的数据库,因为订单列完全依赖于 id 列。
Instead, add this method to you order
model
相反,将此方法添加到您的order
模型中
public function get_order_number()
{
return '#' . str_pad($this->id, 8, "0", STR_PAD_LEFT);
}
If your last order had the id 5
and you would delete it, then the next order would have the id 6
.
如果您的上一个订单具有 id5
并且您将其删除,那么下一个订单将具有 id 6
。
The only possible exception is if you create orders within an transaction. If a transaction is rolled back, the associated order id would be skipped.
唯一可能的例外是您在交易中创建订单。如果事务回滚,则将跳过关联的订单 ID。
回答by Harun
You can use the Laravel ID generator.
您可以使用Laravel ID 生成器。
First Install it:
composer require haruncpi/laravel-id-generator
首先安装它:
composer require haruncpi/laravel-id-generator
Import the class in your controller.
在您的控制器中导入该类。
use Haruncpi\LaravelIdGenerator\IdGenerator;
Now simply use it
现在只需使用它
$prefix = "#";
$id = IdGenerator::generate(['table' => 'your_table_name', 'length' => 9, 'prefix' =>$prefix]);
Output
输出
#00000001
#00000002
#00000003
...
回答by Mahoor13
There is a problem in reading the maximumid and increment it. In heavy servers or parallel requests, two requests may read the same max(id) from MySQL.
有一个在读的最大问题ID和递增它。在繁重的服务器或并行请求中,两个请求可能会从 MySQL 读取相同的 max(id)。
The best way to create unique sequence number is use a sequence table with just one auto increment field.
创建唯一序列号的最佳方法是使用只有一个自动增量字段的序列表。
- First insert new record in the sequence table.
- Then read the last inserted id from db by LAST_INSERT_ID() MySQL function.
- At last you can remove old records lower than your id.
- 首先在序列表中插入新记录。
- 然后通过 LAST_INSERT_ID() MySQL 函数从 db 读取最后插入的 id。
- 最后,您可以删除低于您的 id 的旧记录。
Laravel way:
Laravel 方式:
$id = DB::table('seq_foo')->insertGetId(['id' => null]);
DB::table('seq_foo')->where('id', '<', $id)->delete();
$id is your unique sequence number.
$id 是您的唯一序列号。
回答by Nazmus Shakib
You may try with this:
你可以试试这个:
public function generateOrderNR()
{
$orderObj = \DB::table('orders')->select('order_nr')->latest('id')->first();
if ($orderObj) {
$orderNr = $orderObj->order_nr;
$removed1char = substr($orderNr, 1);
$generateOrder_nr = $stpad = '#' . str_pad($removed1char + 1, 8, "0", STR_PAD_LEFT);
} else {
$generateOrder_nr = '#' . str_pad(1, 8, "0", STR_PAD_LEFT);
}
return $generateOrder_nr;
}
You can generate order_nr
by using this: $this->generateOrderNR();
in your create()
function.
您可以order_nr
通过$this->generateOrderNR();
在create()
函数中使用 this:来生成。
In addition mt_rand()
is 4 times faster than rand()
you may use this for better user experience.
此外,mt_rand()
它比rand()
您使用它的速度快 4 倍,以获得更好的用户体验。
回答by Rajakishore B
I have found a better solution:
我找到了一个更好的解决方案:
$paynowbillprefix1="ADDON-";
$paynowbillprefix1=strlen($paynowbillprefix1);
$query2 = "select gen_id from user_cart_addon order by id desc limit 0, 1";
$exec2 = mysqli_query($conn,$query2) or die ("Error in Query2".mysqli_error());
$res2 = mysqli_fetch_array($exec2);
$num2 = mysqli_num_rows($exec2);
$billnumber = $res2["gen_id"];
$billdigit=strlen($billnumber);
if ($billnumber == '')
{
$billnumbercode ='ADDON-'.'1';
}
else
{
$billnumber = $res2["gen_id"];
$billnumbercode = substr($billnumber,$paynowbillprefix1, $billdigit);
$billnumbercode = intval($billnumbercode);
$billnumbercode = $billnumbercode + 1;
$maxanum = $billnumbercode;
$billnumbercode = 'ADDON-'.$maxanum;
}