QcodeAdd.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <?php
  2. namespace app\admin\controller;
  3. use app\admin\model\QcodeCompany;
  4. use app\admin\model\QcodeGsmc;
  5. use app\admin\model\QcodeProduct;
  6. use app\common\controller\Backend;
  7. use app\admin\model\ResetFlow;
  8. use app\admin\model\QcodeLarge;
  9. use app\admin\model\QcodeBach;
  10. use app\admin\model\QcodeSmall;
  11. use app\admin\model\QcodeLiushui;
  12. use fast\Arr;
  13. use think\Db;
  14. use think\Session;
  15. class QcodeAdd extends Backend
  16. {
  17. /**
  18. * 首页展示
  19. * @return string|\think\response\Json
  20. * @throws \think\Exception
  21. * @throws \think\db\exception\DataNotFoundException
  22. * @throws \think\db\exception\ModelNotFoundException
  23. * @throws \think\exception\DbException
  24. */
  25. public function index()
  26. {
  27. $company = new QcodeCompany();
  28. $product = new QcodeProduct();
  29. $userinfo = Session::get('admin');
  30. $data = [
  31. 'nickname' => $userinfo['company_name'],
  32. 'postcode' => $userinfo['postcode'],
  33. 'mobile' => $userinfo['mobile'],
  34. 'printer_code' => $userinfo['printer_code'],
  35. 'company_address' => $userinfo['company_address']
  36. ];
  37. //创建公司唯一id,进行创建公司对用表名
  38. $user_company_value = Db::name('admin')->where('id', $userinfo['id'])->value('company');
  39. if (empty($user_company_value)) {
  40. $max_company = Db::name('admin')->max('company');
  41. $new_company_value = $max_company ? ($max_company + 1) : 1;
  42. Db::name('admin')->where('id', $userinfo['id'])->update(['company' => $new_company_value]);
  43. } else {
  44. $new_company_value = $user_company_value;
  45. }
  46. $tableNames = [
  47. $new_company_value . '_qcode_bach',
  48. $new_company_value . '_qcode_company',
  49. $new_company_value . '_qcode_large',
  50. $new_company_value . '_qcode_liushui',
  51. $new_company_value . '_qcode_small',
  52. $new_company_value . '_reset_flow',
  53. ];
  54. foreach ($tableNames as $tableName) {
  55. try {
  56. Db::connect('mongodb')->name($tableName)->insert(['init' => 1]);
  57. // 删除测试数据(可选,如果不想保留这个测试数据)
  58. Db::connect('mongodb')->name($tableName)->where('init', 1)->delete();
  59. } catch (\Exception $e) {
  60. echo "创建集合 {$tableName} 失败:" . $e->getMessage();
  61. }
  62. }
  63. $product_id = $company->name((int)$userinfo['company'].'_'.'qcode_company')->where('delete_time','')->column('product_id');
  64. $product_name = [];
  65. foreach ($product_id as $v){
  66. $list = $product->where('_id',$v)->where('delete_time','')->find();
  67. // $product_name[$list['product_code']] = $list['product_name'];
  68. // 添加空值检查
  69. if (!empty($list) && isset($list['product_code']) && isset($list['product_name'])) {
  70. $product_name[$list['product_code']] = $list['product_name'];
  71. } else {
  72. // 记录日志或跳过
  73. error_log("产品ID {$v} 未找到或数据不完整");
  74. continue;
  75. }
  76. }
  77. $this->view->assign('row',$data);
  78. $this->view->assign('product',$product_name);
  79. return $this->view->fetch();
  80. }
  81. /**
  82. * 获取产品信息
  83. * @return \think\response\Json
  84. * @throws \think\db\exception\DataNotFoundException
  85. * @throws \think\db\exception\ModelNotFoundException
  86. * @throws \think\exception\DbException
  87. */
  88. public function product(){
  89. $QcodeProduct = new QcodeProduct();
  90. $ResetFlow = new ResetFlow();
  91. $userinfo = Session::get('admin');
  92. if ($this->request->isAjax() === false){
  93. $this->error('请求错误');
  94. }
  95. $product_code = input('product_code');
  96. if (empty($product_code)){
  97. $this->error('参数错误');
  98. }
  99. $product = $QcodeProduct->where('product_code',$product_code)->find();
  100. if (empty($product)){
  101. $this->error('未找到该产品信息');
  102. }
  103. $flow = $ResetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',substr(json_encode($product['_id']),9,-2))->find();
  104. $row = [
  105. 'temple' => $product['temple'],
  106. 'flow' => isset($flow['l_flow'])?(int)$flow['l_flow']+1:'',
  107. 'bach' => isset($flow['bach_num'])?(int)$flow['bach_num']+1:'',
  108. ];
  109. if (!empty($flow)){
  110. $row['flow'] = $flow['l_flow']+1;
  111. $row['bach'] = $flow['bach_num']+1;
  112. }
  113. return json(['code'=>1,'data'=>$row]);
  114. }
  115. /**
  116. * 增加新批次
  117. * @return void
  118. * @throws \think\db\exception\DataNotFoundException
  119. * @throws \think\db\exception\ModelNotFoundException
  120. * @throws \think\exception\DbException
  121. */
  122. public function add()
  123. {
  124. $product = new QcodeProduct();
  125. $bach = new QcodeBach();
  126. $large = new QcodeLarge();
  127. $small = new QcodeSmall();
  128. $liushui = new QcodeLiushui();
  129. $resetFlow = new ResetFlow();
  130. if ($this->request->isAjax() === false){
  131. $this->error('请求错误');
  132. }
  133. $rows = input('row');
  134. if (empty($rows)){
  135. $this->error('参数错误');
  136. }
  137. $rows = json_decode($rows);
  138. $data = [];
  139. foreach ($rows as $value){
  140. foreach ($value as $k=>$v){
  141. $data[$k] = $v;
  142. }
  143. }
  144. if ($data['danwei'] == 1){
  145. $num = $data['number'];
  146. $tray_num = $data['tray_num'];
  147. $tray_num1 = $data['tray_num'];
  148. $box_number = $data['box_number'];
  149. $small_num = (int)ceil((int)$data['number']/(int)$data['box_number']);
  150. $large_num = (int)ceil($small_num/$tray_num);
  151. }else{
  152. $num = 0;
  153. $tray_num = $data['volume_num'];
  154. $small_num = $data['small_num'];
  155. $large_num = (int)ceil($small_num/$tray_num);
  156. $box_number = 1;
  157. $tray_num1 = 1;
  158. }
  159. //插入批次信息
  160. $userinfo = Session::get('admin');//获取用户信息
  161. $productList = $product->where('product_code',$data['product_code'])->find();//获取材料信息
  162. if (empty($productList)){
  163. $this->error('未找到该产品数据');
  164. }
  165. $batchList = [
  166. 'supplier_name' => $data['company_name'],
  167. 'supplier_code' => $userinfo['printer_code'],
  168. 'kes' => $userinfo['kes'],
  169. 'supplier_id' => $userinfo['id'],
  170. 'matter_name' => $productList['product_name'],
  171. 'matter_no' => $productList['product_code'],
  172. 'matter_id' => substr(json_encode($productList['_id']),9,-2),
  173. 'matter_type' => $productList['temple'],
  174. 'num' => $num,
  175. 'larger_num' => $large_num,
  176. 'small_num' => $small_num,
  177. 'manufacture_date' => (int)date('ymd',strtotime($data['manufacture_date'])),
  178. 'print_date' => (int)date('ymd',strtotime($data['print_date'])),
  179. 'box_num' => $box_number,
  180. 'tray_num' => $tray_num1,
  181. 'l_reservation' => '',
  182. // 'l_flow' => $data['big_liushui'],
  183. 'l_flow' => intval($data['big_liushui']),
  184. 'l_weight' => $data['big_weight'],
  185. 's_flow' => $data['small_start_liushui'],
  186. 's_weight' => $data['small_weight'],
  187. 's_reservation' => '',
  188. 'bach_status' => 0,
  189. 'userid' => $userinfo['id'],
  190. 'bach_num' => $data['batch'],
  191. 'large_endnum' => $data['big_liushui'] + $data['box_num'] -1,
  192. 'create_time' => time(),
  193. ];
  194. //echo "<pre>";
  195. //print_r($batchList);
  196. //echo "<pre>";die;
  197. $res = $bach->save($batchList);
  198. if ($res === 0){
  199. $this->error('添加失败');
  200. }
  201. $flow = [
  202. 'l_flow' => (int)$batchList['large_endnum'],
  203. 'bach_num' => $batchList['bach_num'],
  204. ];
  205. if ($resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_id'])->find()){
  206. $resetFlow->name($userinfo['company'].'_'."reset_flow")->where('product_id',$batchList['matter_id'])->update($flow);
  207. }else{
  208. $flow['product_id'] = $batchList['matter_id'];
  209. $resetFlow->save($flow);
  210. }
  211. $last_id = $bach->getLastInsID();
  212. if ($last_id){
  213. //插入大小二维码数据
  214. //二维码数据不变区域
  215. // echo "<pre>";
  216. // print_r($batchList);
  217. // echo "<pre>";
  218. $fixed_code = '';
  219. $fixed_code.=$this->intTochar($batchList['matter_type'],2);//2位 辅料种类编码
  220. // $fixed_code .= $this->intTochar($batchList['supplier_code'], 21);//21位 供应商编码
  221. $fixed_code .= $this->intTochar($batchList['kes'], 12);//12位 供应商编码
  222. // $fixed_code .= '9'; // 补0一位
  223. // 判断物料编码是否包含'AB'(新物料编码)
  224. if (strpos($batchList['matter_no'], 'AB') !== false) {
  225. // 新物料编码处理逻辑
  226. $fixed_code .= '0000000000'; // 新编码补10个0
  227. // $fixed_code .= $this->intTochar($batchList['matter_no'], 10); // 转换为10位辅料编码
  228. $fixed_code .= $this->intTochar(trim($batchList['matter_no']), 10); // 去掉空格
  229. } else {
  230. // 老物料编码处理逻辑
  231. $fixed_code .= '000'; // 老编码补
  232. // $fixed_code .= $this->intTochar($batchList['matter_no'], 17); // 转换为16位辅料编码
  233. $fixed_code .= $this->intTochar(trim($batchList['matter_no']), 17); // 去掉空格
  234. }
  235. // $fixed_code .= '0000000000'; // 补0一位
  236. // $fixed_code.=$this->intTochar($batchList['matter_no'],10);//10位 辅料编码
  237. $fixed_code.=$batchList['manufacture_date'];//6位 生产日期
  238. $print_code=$batchList['print_date'];//6位 打码日期
  239. $small_liushui = [
  240. 'onlycode' => 'AB92'.$fixed_code.$print_code,
  241. 'last_num' => 0,
  242. 'user_id' => $userinfo['company'],
  243. 'stype' => 2,
  244. 'dateTime' => time(),
  245. ];
  246. $whereSmall = [
  247. 'onlycode' => $small_liushui['onlycode'],
  248. 'user_id' => $userinfo['company'],
  249. ];
  250. //echo "<pre>";
  251. //print_r($whereSmall);
  252. //echo "<pre>";die;
  253. if ($liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find()){
  254. //小件二维码存在,更新小件二维码最后流水号
  255. $lastNum = $liushui->name($userinfo['company'].'_'.'qcode_liushui')->where($whereSmall)->find();
  256. }else{
  257. //小件二维码不存在,新增记录
  258. $liushui->save($small_liushui);
  259. $lastNum['last_num'] = 0;
  260. }
  261. //循环插入大件二维码数据
  262. for ($i=0;$i<$batchList['larger_num'];$i++){
  263. $large = new QcodeLarge();
  264. $l_flow = $this->intTochar($batchList['l_flow']+$i,6);
  265. $l_weight = $this->intTochar($batchList['l_weight']*100,6);
  266. $l_reservation = $this->intTochar($batchList['bach_num'],10);
  267. $l_reservation = $l_reservation.'0000000000';
  268. $remainder = $batchList['small_num'] - $batchList['tray_num'] * $i;//最后一托盘小件数量
  269. if ($remainder < $batchList['tray_num']){
  270. $small_n = $this->intTochar($remainder,3);//3位小件数量,不足补0
  271. }else{
  272. $small_n = $this->intTochar($batchList['tray_num'],3);
  273. }
  274. $l_num = 0;
  275. if ($data['danwei'] == 1){
  276. //以箱为单位时
  277. $l_num = $small_n * $batchList['box_num'];
  278. }
  279. //大件二维码数据
  280. $code_data = $this->CodeData('AB92',$fixed_code,$small_n,$print_code,$l_flow,$l_weight,'2',$l_reservation);
  281. //大码数据信息
  282. $l_data = [
  283. 'bach_id' => $last_id,
  284. 'code' => $code_data['code'],
  285. 'code_cp1' => $code_data['code_cp1'],
  286. 'code_cp2' => $code_data['code_cp2'],
  287. 'print_date' => $print_code,
  288. 'create_time' => time(),
  289. 'p_nums' => 0,
  290. 'userid' =>$userinfo['id'],
  291. 'l_weight' =>$batchList['l_weight']*100,
  292. 'l_num' =>$l_num,
  293. 'l_status' => 0,
  294. 'l_print' => 0
  295. ];
  296. // echo "<pre>";
  297. // print_r($l_data);
  298. // echo "<pre>";die;
  299. $l_res = $large->save($l_data);
  300. if ($l_res === 0){
  301. $this->error('大件码插入失败');
  302. }
  303. $large_id = $large->getLastInsID();
  304. if ($large_id){
  305. // //小件码循环插入
  306. for ($j=0;$j<$tray_num and ($j+$i*$tray_num)<$batchList['small_num'];$j++){
  307. $small = new QcodeSmall();
  308. $s_flow = $this->intTochar($batchList['s_flow']+$j+$i*$tray_num+$lastNum['last_num'],6);//小件码序号从1开始
  309. $s_weight = $this->intTochar($batchList['s_weight'],6);
  310. $small_sign = '000';
  311. $s_reservation = $this->intTochar($batchList['bach_num'],10);
  312. $s_reservation = $s_reservation . '0000000000';
  313. //生成小件码
  314. $small_code_data = $this->CodeData('AB92',$fixed_code,$small_sign,$print_code,$s_flow,$s_weight,'1',$s_reservation);
  315. //小码数据
  316. $s_data = [
  317. 'large_id'=>$large_id,
  318. 'bach_id'=>$last_id,
  319. 'code'=>$small_code_data['code'],
  320. 'code_cp1'=>$small_code_data['code_cp1'],
  321. 'code_cp2'=>$small_code_data['code_cp2'],
  322. 'l_flow'=>$j+1,
  323. 'print_date'=>$print_code,
  324. 'create_time'=>time(),
  325. 'p_nums'=>0,
  326. 'userid'=>$userinfo['id'],//小码绑定用户id
  327. 's_weight'=>$batchList['s_weight'],//单个小件重量
  328. 'status' => 0,
  329. ];
  330. $s_res = $small->save($s_data);
  331. if ($s_res === 0){
  332. $this->error('小件码插入失败');
  333. }
  334. }
  335. }else{
  336. $this->error('添加失败');
  337. }
  338. }
  339. }
  340. $liushui_res = $liushui->name($userinfo['id'].'_'.'qcode_liushui')->where($whereSmall)->update(['last_num'=>$batchList['small_num']]);
  341. if ($liushui_res === false){
  342. $this->error('添加失败');
  343. }
  344. $this->success('成功');
  345. }
  346. /**
  347. * 编码补位
  348. * @param $num
  349. * @param $len
  350. * @return string
  351. */
  352. function intTochar($num=0,$len){
  353. //规定的不足的时候自动补足零,超出时截断,避免二维码字段错位
  354. $code = (string)$num;
  355. if (strlen($code) > $len) {
  356. $code = substr($code, -$len);
  357. }
  358. return str_pad($code, $len, '0', STR_PAD_LEFT);
  359. }
  360. /**
  361. * 二维码编码生成
  362. * @param $sign
  363. * @param $fixed_code
  364. * @param $small_num
  365. * @param $print_date
  366. * @param $flow
  367. * @param $weight
  368. * @param $large_sign
  369. * @param $reservation
  370. * @return array
  371. */
  372. function CodeData($sign,$fixed_code,$small_num,$print_date,$flow,$weight,$large_sign,$reservation){
  373. $code=$sign;//4 位固定标志位
  374. $code.=$fixed_code; // 固定字符串
  375. $code.=$small_num;//3位 小件数量
  376. $code.=$print_date;//6 位 日期
  377. $code.=$flow;//6位打印流水号
  378. $code.=$weight;//6位辅料重量
  379. $code.=$large_sign;//大小件标示位
  380. $code.=$reservation;//20 位 预留号
  381. //大码数据信息
  382. $data=[
  383. 'code'=>str_replace(" ","",$code),
  384. 'code_cp1'=>$print_date.$flow,
  385. 'code_cp2'=>$weight.$reservation,//20位补充
  386. 'print_date'=>time(),
  387. 'p_nums'=>0,
  388. ];
  389. return $data;
  390. }
  391. }