protected function generateCardSecret() { // 生成一个 5 字节的随机字符串,然后将其转换为十六进制表示 $cardSecret = bin2hex(random_bytes(5)); // 将生成的卡密码转换为大写并返回 return strtoupper($cardSecret); } public function adds($num, $money, $batch_id = null) { // 使用关联数组存储已存在的卡号,键为卡号,值为 1(用于快速查找) $cardNumberCache = array_flip(Db::name('card_info')->column('card_number')); $dataArr = []; // 用于存储批量插入的卡片数据 $tempNumberArr = []; // 用于临时存储当前批次生成的卡号 $limit = 1000; // 每次批量插入的卡片数量限制 for ($i = 0; $i < $num; $i++) { // 生成一个特定长度的卡号 $cardNumber = $this->generateCardNumber(10, $batch_id); // 准备卡片数据 $data = [ 'card_number' => $cardNumber, 'card_password' => $this->generateCardSecret(), // 生成卡密码 'batch_id' => $batch_id, // 批次 ID 'money' => $money, // 卡片金额 'status' => 'wait', // 卡片初始状态为等待使用 'createtime' => time() // 创建时间 ]; $dataArr[] = $data; // 将卡片数据添加到批量插入数组中 $tempNumberArr[] = $cardNumber; // 将卡号添加到临时数组中 // 如果达到批量插入的限制数量 if (count($dataArr) >= $limit) { // 执行批量插入操作 Db::name('card_info')->insertAll($dataArr); $dataArr = []; // 重置批量插入数组 // 更新缓存(这里可能需要根据实际业务逻辑实现更新操作) } } // 如果还有剩余未插入的卡片数据 if (!empty($dataArr)) { // 执行最后一批次的插入操作 Db::name('card_info')->insertAll($dataArr); } } protected function generateCardNumber($num = 10, $batch_id) { do { $cardNumber = $batch_id; // 初始化卡号为批次 ID // 如果批次 ID 长度不足 4 位,则在左侧补 0 直到长度为 4 $cardNumber = str_pad($cardNumber, 4, '0', STR_PAD_LEFT); // 循环生成剩余位数的随机数字 for ($i = 4; $i < $num; $i++) { $cardNumber .= rand(0, 9); // 每次添加一个 0-9 的随机数字 } // 检查生成的卡号是否已存在 } while (isset($this->cacheArr[$cardNumber])); // 将生成的唯一卡号添加到缓存数组中 $this->cacheArr[$cardNumber] = 1; // 返回生成的唯一卡号 return $cardNumber; }