技能支持:李维LEVI

前 言

最近由于公司有个业务须要天生30多万个优惠券编码长度在6-8位,网上百度了许多方法创造都不适用此场景。
常规方法天生数据库循环比拟太耗性能,我团队的同事自己写了一个大略且高效的算法,借此为产品经理们也来点硬菜。

php优惠券生成微电商优惠券兑换码算法设计 RESTful API

正文↓

把字母数字随机组合成三个数组,然后根据数据库存的自增id的每个数字作为下标去取字符,拼接成须要的编码。
各位数字最大是9,以是只能取到下标为9的,数组设定为十个字符。

1.先获取数据库存的末了一条id如果没有从1开始。

2.判断id长度与传来的编码长度是否同等,如果小于传来的编码长度时根据id每个位数的数字分别取到字符,剩余的调用随机字符拼接。
如果即是传来的编码长度直接全部获取

3.参数定义

$post[‘num’] 须要天生的数量

$post[‘length’]须要天生的优惠券编码长度

$post[‘type’]须要利用的编码数组

我这里还有额外参数是我数据库存的优惠券id

/

[index 自动天生优惠券编码]

@return [type] [description]

/

public function index()

{

$coupon = new ShopCoupon();

$record = new ShopCouponRecord();

$post = request()->post();

// 检测天生数量

if(!isset($post['num']) || $post['num'] == '' || $post['num'] == 0 || $post['num'] > 10000){

$this->error('数量缺点');

}

// 检测优惠券码长度

if(!isset($post['length']) || $post['length'] == '' || $post['length'] < 6 || $post['length'] > 8){

$this->error('优惠券码长度缺点');

}

// 检测用是否选择优惠券

if (!isset($post['coupon_id']) || $post['coupon_id'] == '' || $post['coupon_id'] < 0) {

$this->error('请选择优惠券');

}

// 检测是否传来编码类型

if (isset($post['type']) && $post['type'] != '') {

$type = $post['type'];

} else {

$type = 1;

}

// 编码数组

if ($type == 1) {

$arr = ['F', 'J', 9, 'R', 6, 'Q', 'S', 3, 'M', 'C'];

} elseif ($type == 2) {

$arr = ['W', 'X', 'Y', 1, 'K', 'O', 'L', 8, 'G', 'B'];

} else {

$arr = ['Z', 4, 'D', 'T', 2, 'H', 7, 'U', 'P', 5];

}

// 自定义一个优惠券编码记录id

$coupon_record_id = 1;

// 根据优惠券id获取优惠券是否已经天生过编码

$record_data = $record->order('id desc')->find();

if ($record_data) {

$coupon_record_id = $record_data['id'] + 1;

}

$data = [];

for ($iiii = 0; $iiii < $post['num']; $iiii++) {

// 检测优惠券编码id长度是否大于1

if (mb_strlen($coupon_record_id) > 1) {

// 判断优惠券编码id长度是否与传来的编码长度同等

if (mb_strlen($coupon_record_id) == $post['length']) {

$coupon_no = '';

// 如果长度即是优惠券长度 优惠券编码id转成数组

$coupon_record_id_arr = str_split($coupon_record_id);

for ($ii = 0; $ii < count($coupon_record_id_arr); $ii++) {

$coupon_no .= $arr[$coupon_record_id_arr[$ii]];

}

} else {

// 优惠券编码id长度小于编码长度 须要判断查了几位

$coupon_no = '';

// 如果长度即是优惠券长度 优惠券编码id转成数组

$coupon_record_id_arr = str_split($coupon_record_id);

for ($iiiiii = 0; $iiiiii < count($coupon_record_id_arr); $iiiiii++) {

$coupon_no .= $arr[$coupon_record_id_arr[$iiiiii]];

}

$coupon_no .= $this->getString($post['length'] - mb_strlen($coupon_record_id), $type);

}

} else {

// 优惠券编码id长度小于编码长度 须要判断查了几位

$coupon_no = '';

$coupon_no .= $arr[$coupon_record_id];

$coupon_no .= $this->getString($post['length'] - 1, $type);

}

$data[$iiii]['coupon_id'] = $post['coupon_id'];

$data[$iiii]['coupon_no'] = $coupon_no;

$data[$iiii]['create_time'] = time();

$coupon_record_id += 1;

}

$re = $record->saveAll($data);

if ($re) {

$this->success('ok', $re);

} else {

$this->error('NO');

}

}

/

[getString 获取随机字符串]

@param int $lent 字符串长度

@return [type] [description]

/

public function getString($lent = 0, $type = 1)

{

if ($lent <= 0) {

return false;

}

if ($type == 1) {

$string = 'AZWXEDVTGBYHNUIKOLP';

} elseif ($type == 2) {

$string = 'QAZSEDCRFVTHNUJMIP';

} else {

$string = 'QAWSXECRFVGBYNJMIKOL';

}

$str = '';

for ($i = 0; $i < $lent; $i++) {

$index = rand(0, strlen($string) - 1);

$str .= $string[$index];

}

return $str;

}

把稳:

编码数组和随机字符串是相互对应的,字母涌如今编码数组中之后下面随机字符串就不能涌现(如果涌现就会重复)。

编码数组字母位置定义好之后不要改动。

缺陷:

编码长度越永生成的越多,当你须要六位编码时最多天生999999个,须要四位大量编码慎用

附上我天生的截图 (一次五万个大约30秒旁边)

文章末了给大家先容一下我的同事-PHP程序员