diff --git a/application/ZengJieCode/controller/admin/Printaction.php b/application/ZengJieCode/controller/admin/Printaction.php index e54caa1..8ad6b66 100644 --- a/application/ZengJieCode/controller/admin/Printaction.php +++ b/application/ZengJieCode/controller/admin/Printaction.php @@ -22,10 +22,57 @@ class Printaction extends Base protected $fontPath = 'public/tsf/jc.ttf'; // 请替换为你的字体文件路径 // 显示条形码生成页面 - public function print_device_barcode_index() + public function print_device_data_index() { - return $this->fetch(); + + $data = input(); + if(array_key_exists('type',$data)){ + return $this->print_device_data_index_action('down'); + }else{ + $result = $this->print_device_data_index_action('page'); + $this->assign([ + 'data' => $result + ]); + return $this->fetch(); + } + } + + public function print_device_data_index_action($data){ + $zengjie = Db::connect('zengjie_db'); + $pc = $zengjie->table('box_code_all')->order('id desc')->find(); + // dump($pc); + $sql = "SELECT + a.mac_code, + a.sn_code, + b.box_code, + FORMAT(b.box_num, '000') AS box_num + FROM + sn_code_all AS a + LEFT JOIN + box_code_all AS b ON a.batch_id = b.id + WHERE + a.batch_id IS NOT NULL + AND b.box_code = ? + ORDER BY + a.batch_id"; + + $result = $zengjie->query($sql, [$pc['box_code']]); + if($data == 'page'){ + return $result; + }else{ + $result2 = [ + ['Mac码','Sn码','箱号'] + ]; + for ($i=0; $i < count($result); $i++) { + $result2[] = [$result[$i]['mac_code'],$result[$i]['sn_code'],$result[$i]['box_code'].'-'.$result[$i]['box_num']]; + } + $excel = new \app\download\controller\Excel(); + $excel->export($result2, $pc['box_code']); + } + } + + // 显示外箱码生成页面 public function print_outside_box_index() { diff --git a/application/ZengJieCode/controller/app/Savemsg.php b/application/ZengJieCode/controller/app/Savemsg.php index a6676fd..b316b81 100644 --- a/application/ZengJieCode/controller/app/Savemsg.php +++ b/application/ZengJieCode/controller/app/Savemsg.php @@ -18,11 +18,6 @@ class Savemsg extends Base{ ]; protected $name_default = 0; - protected $kitchenscale_db_msg = [ - 'cookbook'=>'app_user_cookbook',//菜谱表 - 'foodlist3'=>'app_z_national_standard_food_type_3',//食材列表3 - 'user'=>'app_user_data',//banner - ]; // 加 bcadd(,,20) // 减 bcsub(,,20) @@ -54,7 +49,7 @@ class Savemsg extends Base{ } - public function save_sn_msg($data = ['sn_code'=>'564654564654654','bl_name'=>'bl_5520']){ + public function save_sn_msg($data = ['sn_code'=>'564654564654654','mac_code'=>'ce:sh:yo:ng:d1','bl_name'=>'bl_5520']){ try { // 你的业务逻辑 if(count(input('post.')) > 0){ @@ -66,12 +61,18 @@ class Savemsg extends Base{ if(!array_key_exists('bl_name', $data)){ return $this->msg(10001); } + if(!array_key_exists('mac_code', $data)){ + return $this->msg(10001); + } if(!$this->verify_data_is_ok($data['sn_code'],'str')){ return $this->msg(10005); } if(!$this->verify_data_is_ok($data['bl_name'],'str')){ return $this->msg(10005); } + if(!$this->verify_data_is_ok($data['mac_code'],'str')){ + return $this->msg(10005); + } $result = $this->save_sn_msg_action($data); return $result; } catch (\Exception $e) { @@ -217,6 +218,7 @@ class Savemsg extends Base{ $result = $zengjie->table('sn_code_all')->insert([ 'sn_code'=>$data['sn_code'], 'bluetooth_name'=>$data['bl_name'], + 'mac_code'=>$data['mac_code'], 'create_time'=>date('Y-m-d H:i:s'), ]); if($result){ @@ -226,47 +228,82 @@ class Savemsg extends Base{ } } - public function save_box_msg_action($data){ + public function save_box_msg_action($data) { $zengjie = Db::connect('zengjie_db'); - - $box_num = $zengjie->table('box_code_all')->where(['box_code'=>$data['box_serial_number']])->count(); - $box_num = $box_num+1; - $result = $zengjie->table('box_code_all')->insert([ - 'box_code'=>$data['box_serial_number'], - 'box_num'=>$box_num, - 'create_time'=>date('Y-m-d H:i:s'), - 'content_str'=>$data['sn_code_all'], - ]); - - if($result){ - return $this->msg([]); - }else{ - return $this->msg(10002,'录入失败'); + + // 1. 检查sn_code_all中是否有重复数据 + $snCodes = explode(',', $data['sn_code_all']); + if (count($snCodes) !== count(array_unique($snCodes))) { + return $this->msg(10003, 'SN码列表中存在重复数据'); } - // try { - // // 使用事务闭包,TP5会自动管理事务 - // $result = $zengjie->transaction(function() use ($zengjie, $data) { - // $sn_code = $zengjie->table('box_code_all')->where(['box_code'=>$data['box_serial_number']])->count(); - // $num = $sn_code+1; + // 2. 检查这些SN码是否都存在于sn_code_all表中 + $existCount = $zengjie->table('sn_code_all') + ->where('sn_code', 'in', $snCodes) + ->count(); + + if ($existCount !== count($snCodes)) { + return $this->msg(10004, '存在未登记的SN码'); + } + Db::startTrans(); + try{ + $count = $zengjie->table('box_code_all') + ->where(['box_code'=>$data['box_serial_number']]) + ->count(); + $num = $count + 1; - // $box_id = $zengjie->table('box_code_all')->insertGetId([ - // 'box_code'=>$data['box_serial_number'], - // 'box_num'=>$num, - // 'create_time'=>date('Y-m-d H:i:s'), - // ]); - - // // 使用安全的参数绑定方式 - // $snCodes = explode(',', $data['sn_code_all']); - // $zengjie->table('sn_code_all') - // ->where('sn_code', 'in', $snCodes) - // ->update(['batch_id' => $box_id]); - - // return $box_id; - // }); + $box_id = $zengjie->table('box_code_all')->insertGetId([ + 'box_code' => $data['box_serial_number'], + 'box_num' => $num, + 'create_time' => date('Y-m-d H:i:s'), + 'content_str' => $data['sn_code_all'], + ]); - // return $this->msg(['id'=>$result]); + $affectedRows = $zengjie->table('sn_code_all') + ->where('sn_code', 'in', $snCodes) + ->update(['batch_id' => $box_id]); + + // 检查更新是否影响了预期的行数 + if ($affectedRows !== count($snCodes)) { + throw new \Exception('更新SN码数量不匹配'); + } + Db::commit(); + return $this->msg(['id'=>$box_id]); + } catch (\Exception $e) { + // 回滚事务 + Db::rollback(); + return $this->msg(10002, '录入失败: ' . $e->getMessage()); + } + // // 显式事务控制 + // $zengjie->startTrans(); + // try { + // $count = $zengjie->table('box_code_all') + // ->where(['box_code'=>$data['box_serial_number']]) + // ->count(); + // $num = $count + 1; + + // $box_id = $zengjie->table('box_code_all')->insertGetId([ + // 'box_code' => $data['box_serial_number'], + // 'box_num' => $num, + // 'create_time' => date('Y-m-d H:i:s'), + // 'content_str' => $data['sn_code_all'], + // ]); + + // $affectedRows = $zengjie->table('sn_code_all') + // ->where('sn_code', 'in', $snCodes) + // ->update(['batch_id' => $box_id]); + + // // 检查更新是否影响了预期的行数 + // if ($affectedRows !== count($snCodes)) { + // throw new \Exception('更新SN码数量不匹配'); + // } + + // $zengjie->commit(); + // return $this->msg(['id'=>$box_id]); // } catch (\Exception $e) { + // if ($zengjie->getPdo()->inTransaction()) { + // $zengjie->rollback(); + // } // trace('保存盒信息失败: ' . $e->getMessage(), 'error'); // return $this->msg(10002, '录入失败: ' . $e->getMessage()); // } @@ -301,5 +338,61 @@ class Savemsg extends Base{ return $this->msg(10002,'打印失败'); } } + + ######################################################测试######################################################### + ######################################################测试######################################################### + ######################################################测试######################################################### + + public function ceshiyong(){ + // // 添加测试一维码数据 + // $data = []; + // for ($i = 0; $i < 500; $i++) { + // // 生成15位随机数字作为sn_code + // $sn_code = ''; + // for ($j = 0; $j < 15; $j++) { + // $sn_code .= mt_rand(0, 9); + // } + + // // 生成随机的MAC地址 + // $mac_parts = []; + // for ($k = 0; $k < 6; $k++) { + // $mac_parts[] = sprintf('%02x', mt_rand(0, 255)); + // } + // $mac_code = implode(':', $mac_parts); + + // // 构建数据数组 + // $data[] = [ + // 'sn_code' => $sn_code, + // 'mac_code' => $mac_code, + // 'create_time' => date('Y-m-d H:i:s'), + // 'is_print' => 1, + // 'bluetooth_name' => 'bl_5520' + // ]; + // } + // $zengjie = Db::connect('zengjie_db'); + // $result = $zengjie->table('sn_code_all')->insertAll($data); + // dump($result); + // die; + // // 添加测试一维码数据 + + // 添加测试打包数据 + $zengjie = Db::connect('zengjie_db'); + $records = $zengjie->table('sn_code_all') + ->where('batch_id', 'null') // 或者使用 ->whereNull('batch_id') + ->orderRaw('NEWID()') // SQL Server的随机排序函数 + ->limit(10) + ->select(); + $data['sn_code_all'] = []; + $data['box_serial_number'] = '3ST011527003'; + for ($i=0; $i < count($records); $i++) { + $data['sn_code_all'][] = $records[$i]['sn_code']; + } + $data['sn_code_all'] = implode(',',$data['sn_code_all']); + $result = $this->save_box_msg_action($data); + dump($result); + dump($data); + // 添加测试打包数据 + // return $data; + } } \ No newline at end of file diff --git a/application/ZengJieCode/view/admin/printaction/print_device_barcode_index.html b/application/ZengJieCode/view/admin/printaction/print_device_barcode_index.html deleted file mode 100644 index 42144b0..0000000 --- a/application/ZengJieCode/view/admin/printaction/print_device_barcode_index.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - 标签打印系统 - - - - -

标签打印系统

-
440×147px图片打印到60×20mm标签纸
- -
- -
- - - - - - \ No newline at end of file diff --git a/application/ZengJieCode/view/admin/printaction/print_device_data_index.html b/application/ZengJieCode/view/admin/printaction/print_device_data_index.html new file mode 100644 index 0000000..c55bee0 --- /dev/null +++ b/application/ZengJieCode/view/admin/printaction/print_device_data_index.html @@ -0,0 +1,71 @@ + + + + + + 最近一次打印数据 + + + + +
+ + + + + + + {volist name="data" id="item"} + + + + + + {/volist} +
MAC地址SN码箱号
{$item.mac_code|default='未分配'}{$item.sn_code}{$item.box_code}-{$item.box_num}
+
点击下载
+
+ + + \ No newline at end of file diff --git a/application/download/controller/Excel.php b/application/download/controller/Excel.php new file mode 100644 index 0000000..5f658d2 --- /dev/null +++ b/application/download/controller/Excel.php @@ -0,0 +1,205 @@ + '五月订单', // 工作表名称 + // 'header_style' => [ + // 'font' => [ + // 'bold' => true, + // 'color' => ['argb' => 'FFFFFFFF'] // 白色文字 + // ], + // 'fill' => [ + // 'fillType' => Fill::FILL_SOLID, + // 'startColor' => ['argb' => 'FF0070C0'] // 蓝色背景 + // ], + // 'alignment' => [ + // 'horizontal' => Alignment::HORIZONTAL_CENTER, + // ], + // ], + // 'stripe_color1' => 'FFE6F1FF', // 浅蓝色 + // 'stripe_color2' => 'FFD6E6FF', // 稍深一点的蓝色 + // ]; + + // $excel = new \app\download\controller\Excel(); + // $excel->export($data, '五月订单报表', $options); + // } + + + + + /** + * 导出 Excel 文件(带斑马纹效果) + * + * @param array $data 要导出的数据,格式为二维数组,第一行为表头 + * @param string $filename 下载的文件名(不带扩展名) + * @param array $options 可选配置项 + * - 'sheet_title' => string 工作表标题 + * - 'header_style' => array 自定义表头样式 + * - 'content_style' => array 自定义内容样式 + * - 'zebra_stripe' => bool 是否启用斑马纹效果(默认true) + * - 'stripe_color1' => string 斑马纹第一种颜色(默认白色) + * - 'stripe_color2' => string 斑马纹第二种颜色(默认浅灰色) + * - 'auto_width' => bool 是否自动调整列宽 + * @return void + */ + public function export(array $data, string $filename = 'export', array $options = []) + { + // 验证数据 + if (empty($data) || !is_array($data) || !is_array($data[0])) { + throw new \InvalidArgumentException('导出数据格式不正确,应为二维数组且第一行为表头'); + } + + // 默认配置 + $defaultOptions = [ + 'sheet_title' => 'Sheet1', + 'header_style' => [ + 'font' => ['bold' => true], + 'fill' => [ + 'fillType' => Fill::FILL_SOLID, + 'startColor' => ['argb' => Color::COLOR_YELLOW], + ], + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + 'borders' => [ + 'outline' => ['borderStyle' => Border::BORDER_THIN], + 'inside' => ['borderStyle' => Border::BORDER_THIN] + ], + ], + 'content_style' => [ + 'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER], + 'borders' => [ + 'outline' => ['borderStyle' => Border::BORDER_THIN], + 'inside' => ['borderStyle' => Border::BORDER_THIN] + ], + ], + 'zebra_stripe' => true, // 默认启用斑马纹 + 'stripe_color1' => 'FFFFFFFF', // 白色 + 'stripe_color2' => 'FFEEEEEE', // 浅灰色 + 'auto_width' => true, + ]; + + // 合并用户配置和默认配置 + $options = array_merge($defaultOptions, $options); + + // 创建 Spreadsheet 对象 + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $sheet->setTitle($options['sheet_title']); + + // 获取列数和行数 + $columnCount = count($data[0]); + $rowCount = count($data); + + // 写入数据 + foreach ($data as $rowIndex => $rowData) { + for ($colIndex = 0; $colIndex < $columnCount; $colIndex++) { + $sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex + 1, $rowData[$colIndex]); + } + } + + // 设置表头样式 + $headerRange = 'A1:' . $this->getExcelColumnName($columnCount) . '1'; + $sheet->getStyle($headerRange)->applyFromArray($options['header_style']); + + // 设置内容样式 + $contentRange = 'A2:' . $this->getExcelColumnName($columnCount) . $rowCount; + $sheet->getStyle($contentRange)->applyFromArray($options['content_style']); + + // ============================================= + // 重点:斑马纹效果实现 + // ============================================= + if ($options['zebra_stripe']) { + $this->applyZebraStripe( + $sheet, + $columnCount, + $rowCount, + $options['stripe_color1'], + $options['stripe_color2'] + ); + } + + // 自动调整列宽 + if ($options['auto_width']) { + for ($colIndex = 1; $colIndex <= $columnCount; $colIndex++) { + $sheet->getColumnDimensionByColumn($colIndex)->setAutoSize(true); + } + } + + // 设置响应头以触发文件下载 + header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); + header('Content-Disposition: attachment;filename="' . $filename . '.xlsx"'); + header('Cache-Control: max-age=0'); + + // 保存并输出 Excel 文件 + $writer = new Xlsx($spreadsheet); + $writer->save('php://output'); + exit; + } + + /** + * 应用斑马纹效果(核心实现) + * + * @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet + * @param int $columnCount 总列数 + * @param int $totalRows 总行数(包括表头) + * @param string $color1 第一种颜色 + * @param string $color2 第二种颜色 + */ + protected function applyZebraStripe($sheet, $columnCount, $totalRows, $color1, $color2) + { + // 从第二行开始应用斑马纹(跳过表头) + for ($rowIndex = 2; $rowIndex <= $totalRows; $rowIndex++) { + // 计算当前行应该使用哪种颜色 + $color = ($rowIndex % 2 == 0) ? $color1 : $color2; + + // 设置行样式 + $rowStyle = [ + 'fill' => [ + 'fillType' => Fill::FILL_SOLID, + 'startColor' => ['argb' => $color], + ], + ]; + + // 应用样式到整行 + $range = 'A' . $rowIndex . ':' . $this->getExcelColumnName($columnCount) . $rowIndex; + $sheet->getStyle($range)->applyFromArray($rowStyle); + } + } + + /** + * 获取 Excel 列名 + * + * @param int $index 列索引(从1开始) + * @return string Excel 列名 + */ + protected function getExcelColumnName($index) + { + $columnName = ''; + while ($index > 0) { + $remainder = ($index - 1) % 26; + $columnName = chr(65 + $remainder) . $columnName; + $index = intval(($index - 1) / 26); + } + return $columnName; + } +} \ No newline at end of file diff --git a/application/route.php b/application/route.php index 9ad52e4..4a00123 100644 --- a/application/route.php +++ b/application/route.php @@ -606,11 +606,13 @@ Route::any('/k/a/cookbook/stop_and_run', 'app/kitchenscale/admin.cookbook/stop_a Route::any('/z/config_msg', 'app/ZengJieCode/app.savemsg/config_msg'); Route::any('/z/save_sn_msg', 'app/ZengJieCode/app.savemsg/save_sn_msg'); Route::any('/z/save_box_msg', 'app/ZengJieCode/app.savemsg/save_box_msg'); +// 测试用 +Route::any('/z/ceshiyong', 'app/ZengJieCode/app.savemsg/ceshiyong'); // 重新打印 Route::any('/z/print_again', 'app/ZengJieCode/app.savemsg/print_again'); -Route::any('/z/print_device_barcode_index', 'app/ZengJieCode/admin.printaction/print_device_barcode_index'); -Route::any('/z/print_outside_box_index', 'app/ZengJieCode/admin.printaction/print_outside_box_index'); +Route::any('/z/print_device_data_index', 'app/ZengJieCode/admin.printaction/print_device_data_index'); +// Route::any('/z/print_outside_box_index', 'app/ZengJieCode/admin.printaction/print_outside_box_index'); // 获取蓝牙录入的未打印条码 Route::any('/z/print_device_barcode', 'app/ZengJieCode/admin.printaction/print_device_barcode'); @@ -619,6 +621,8 @@ Route::any('/z/print_scan_barcode', 'app/ZengJieCode/admin.printaction/print_sca // 获取大箱没打印的条码 Route::any('/z/print_combined_code', 'app/ZengJieCode/admin.printaction/print_combined_code'); + + ################################################################下面是设备入库录入################################################################ ################################################################################################################################################ // 默认配置