WorkOrder.php 86 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  5. use PhpOffice\PhpSpreadsheet\Writer\Pdf\Tcpdf;
  6. use think\Config;
  7. use think\Db;
  8. use think\Request;
  9. use PhpOffice\PhpSpreadsheet\IOFactory;
  10. use function fast\e;
  11. /**
  12. * 工单资料管理
  13. */
  14. class WorkOrder extends Api
  15. {
  16. protected $noNeedLogin = ['*'];
  17. protected $noNeedRight = ['*'];
  18. public function _initialize()
  19. {
  20. if (isset($_SERVER['HTTP_ORIGIN'])) {
  21. header('Access-Control-Expose-Headers: __token__');//跨域让客户端获取到
  22. }
  23. //跨域检测
  24. check_cors_request();
  25. if (!isset($_COOKIE['PHPSESSID'])) {
  26. Config::set('session.id', $this->request->server("HTTP_SID"));
  27. }
  28. parent::_initialize();
  29. }
  30. /**
  31. * 工单资料菜单列表
  32. *
  33. * @ApiMethod (GET)
  34. * @return false|string
  35. * @throws \think\Exception
  36. */
  37. public function DataList()
  38. {
  39. $where['j.Mod_rq'] = null;
  40. $allCustomers = \db('erp_客户供应商')->alias('e')
  41. ->field('e.编号 as 客户编号')
  42. ->select();
  43. $customerData = [];
  44. foreach ($allCustomers as $customer) {
  45. $customerID = $customer['客户编号'];
  46. $customerData[$customerID] = ['计划中' => 0, '生产中' => 0];
  47. }
  48. $data = \db('erp_客户供应商')->alias('e')
  49. ->join('工单_基本资料 j', 'e.编号 = j.客户编号', 'LEFT')
  50. ->field('e.编号 as 客户编号, j.订单编号, j.gd_statu')
  51. ->where($where)
  52. ->select();
  53. foreach ($data as $row) {
  54. $customerID = $row['客户编号'];
  55. $status = $row['gd_statu'];
  56. if ($status == '1-计划中') {
  57. $customerData[$customerID]['计划中']++;
  58. } elseif ($status == '2-生产中') {
  59. $customerData[$customerID]['生产中']++;
  60. }
  61. }
  62. ksort($customerData);
  63. $output = [];
  64. foreach ($customerData as $customerID => $statusCounts) {
  65. $statusString = [];
  66. if ($statusCounts['计划中'] > 0) {
  67. $statusString[] = "计划中:{$statusCounts['计划中']}";
  68. }
  69. if ($statusCounts['生产中'] > 0) {
  70. $statusString[] = "生产中:{$statusCounts['生产中']}";
  71. }
  72. $output[] = "{$customerID}【" . implode(' ', $statusString) . "】";
  73. }
  74. $this->success('成功', $output);
  75. }
  76. /**
  77. * 工单基本资料列表
  78. * @ApiMethod (GET)
  79. * @param string $limit 查询长度
  80. * @param string $Gd_khdh 客户代号
  81. * @param string $startTime 接单日期开始时间
  82. * @param string $endTime 接单日期结束时间
  83. * @return \think\response\Json
  84. * @throws \think\exception\DbException
  85. */
  86. public function WorkOrderList()
  87. {
  88. if ($this->request->isGet() === false) {
  89. $this->error('请求错误');
  90. }
  91. $search = input('search');
  92. $page = input('page');
  93. $limit = input('limit');
  94. $param = $this->request->param();
  95. $where = [];
  96. if (!empty($search)) {
  97. $where['订单编号|生产款号|客户编号|款式|审核|Sys_id'] = ['like', '%' . $search . '%'];
  98. }
  99. $where['Mod_rq'] = null;
  100. $list = \db('工单_基本资料')
  101. ->where($where)
  102. ->order('订单编号 desc, Gd_statu desc, Sys_rq desc')
  103. ->limit(($page - 1) * $limit, $limit)
  104. ->select();
  105. $count = \db('工单_基本资料')
  106. ->where($where)
  107. ->order('订单编号 desc, Gd_statu desc, Sys_rq desc')
  108. ->select();
  109. // 提取所有订单编号
  110. $orderIds = array_column($list, '订单编号');
  111. // 查询所有在“工单_相关附件”表中存在的订单编号
  112. $relatedOrders = \db('工单_相关附件')
  113. ->whereIn('关联编号', $orderIds)
  114. ->whereIn('附件备注', '技术附件')
  115. ->column('关联编号');
  116. // 遍历数据,判断每个订单编号是否在相关附件表中
  117. foreach ($list as &$value) {
  118. if (in_array($value['订单编号'], $relatedOrders)) {
  119. $value['status'] = ''; // 有相关附件,status为空
  120. } else {
  121. $value['status'] = '*'; // 没有相关附件,标记为新订单
  122. }
  123. }
  124. $this->success('成功', ['data' => $list, 'total' => count($count)]);
  125. }
  126. /**
  127. * 月度客户订单汇总
  128. */
  129. public function ProductInformation()
  130. {
  131. if ($this->request->isGet() === false) {
  132. $this->error('请求错误');
  133. }
  134. // 查询生产中和未生产的数据,使用 CASE WHEN 进行分类统计
  135. $data = \db('工单_基本资料')->alias('j')
  136. ->field('
  137. j.客户编号,
  138. REPLACE(DATE_FORMAT(j.Sys_rq, "%Y-%m"), "-", "") as 年月,
  139. SUM(CASE WHEN j.gd_statu = "2-生产中" THEN 1 ELSE 0 END) as 生产中数量,
  140. SUM(CASE WHEN j.gd_statu = "1-计划中" THEN 1 ELSE 0 END) as 未生产数量
  141. ')
  142. ->where('j.Mod_rq', null) // 统一的查询条件
  143. ->group('j.客户编号, 年月')
  144. ->order('j.客户编号 asc')
  145. ->select();
  146. // 格式化数据
  147. $result = [];
  148. foreach ($data as $item) {
  149. $result[$item['年月']][] = $item['客户编号'] . '【生产中' . $item['生产中数量'] . ',计划中' . $item['未生产数量'] . '】';
  150. }
  151. $this->success('请求成功', ['data' => $result]);
  152. }
  153. /**
  154. * U8工单资料删除
  155. * @param string $workOrder 工单编号
  156. * @return void
  157. * @throws \think\Exception
  158. * @throws \think\exception\PDOException
  159. */
  160. public function orderDataDel()
  161. {
  162. if($this->request->isGet() === false){
  163. $this->error('请求错误');
  164. }
  165. $workOrder = input('Uniqid');
  166. if (empty($workOrder)){
  167. $this->error('参数错误');
  168. }
  169. $order = \db('工单_基本资料')->where('UniqId',$workOrder)->find();
  170. \db()->startTrans();
  171. try {
  172. \db('工单_印件资料')->where('订单编号',$order['订单编号'])->update(['Mod_rq'=>date('Y-m-d H:i:s')]);
  173. \db('工单_工艺资料')->where('订单编号',$order['订单编号'])->update(['Mod_rq'=>date('Y-m-d H:i:s')]);
  174. $res = \db('工单_基本资料')->where('UniqId',$workOrder)->update(['Mod_rq'=>date('Y-m-d H:i:s')]);
  175. \db()->commit();
  176. } catch (\Exception $e){
  177. \db()->rollback();
  178. }
  179. if ($res !== false){
  180. $this->success('成功');
  181. }else{
  182. $this->error('失败');
  183. }
  184. }
  185. /**
  186. * 印件资料修改
  187. * @ApiMethod (POST)
  188. * @param void
  189. * @return void
  190. * @throws \think\Exception
  191. * @throws \think\exception\PDOException
  192. */
  193. public function PrintedEdit()
  194. {
  195. if (Request::instance()->isPost() === false){
  196. $this->error('请求错误');
  197. }
  198. $param = Request::instance()->post();
  199. if (empty($param) || isset($param['Uniqid']) === false){
  200. $this->error('参数错误');
  201. }
  202. $param['Yj_Gdbh'] = \db('工单_印件资料')->where('Uniqid',$param['Uniqid'])->value('Yj_Gdbh');
  203. $data = [
  204. 'Yj_Gdbh' =>$param['Yj_Gdbh'],
  205. 'yj_Yjno' =>$param['yjno'],
  206. 'yj_Yjdh' =>$param['yjdh'],
  207. 'yj_yjmc' =>$param['yjmc'],
  208. 'yj_zzdh' =>$param['zzdh'],
  209. 'yj_zzdh1' =>$param['zzdh1'],
  210. 'yj_zzdh2' =>$param['zzdh2'],
  211. 'yj_zzdh3' =>$param['zzdh3'],
  212. 'yj_zzdh4' =>$param['zzdh4'],
  213. 'yj_zzmc' =>$param['zzmc'],
  214. 'yj_zzmc1' =>$param['zzmc1'],
  215. 'yj_zzmc2' =>$param['zzmc2'],
  216. 'yj_zzmc3' =>$param['zzmc3'],
  217. 'yj_zzmc4' =>$param['zzmc4'],
  218. 'yj_tlgg' =>$param['tlgg'],
  219. 'yj_klgg' =>$param['klgg'],
  220. 'Yj_核算规格' =>$param['hsgg'],
  221. 'yj_成品数量' =>$param['cpsl'],
  222. 'yj_平张投料' =>$param['pztl'],
  223. 'yj_ks' =>$param['ks'],
  224. 'yj_ls' =>$param['ls'],
  225. 'yj_desc' =>$param['desc'],
  226. ];
  227. $UniqId = $param['Uniqid'];
  228. $sql = \db('工单_印件资料')->where('Uniqid',$UniqId)->fetchSql(true)->update($data);
  229. $res = Db::query($sql);
  230. $process = \db('工单_工艺资料')
  231. ->where('Gy0_gdbh',$data['Yj_Gdbh'])
  232. ->where('Gy0_yjno',$data['yj_Yjno'])
  233. ->select();
  234. if ((int)$data['yj_平张投料'] > 0 && !empty($process)){
  235. //重新分配工序计划产量
  236. $result = $this->PlannedProcessYield($data['Yj_Gdbh'],$data['yj_Yjno'],0,$data['yj_平张投料']);
  237. if ($result === false){
  238. $this->success('修改工序产量失败');
  239. }
  240. }
  241. if ($res !== false){
  242. $this->success('成功');
  243. }else{
  244. $this->error('失败');
  245. }
  246. }
  247. /**
  248. * 工艺资料修改
  249. * @ApiMethod (POST)
  250. */
  251. public function ProcessDetailEdit()
  252. {
  253. if (Request::instance()->isPost() === false){
  254. $this->error('请求错误');
  255. }
  256. $param = Request::instance()->post();
  257. if (empty($param) || isset($param['UniqId']) === false){
  258. $this->error('参数错误');
  259. }
  260. if (empty($param['Gy0_shdh'])){
  261. $rate['rate0'] = 0;
  262. $rate['rate1'] = 0;
  263. }else{
  264. $rate = \db('dic_lzsh')->where('sys_bh',$param['Gy0_shdh'])->field('rtrim(sys_rate0) as rate0,rtrim(sys_rate1) as rate1')->find();
  265. }
  266. $param['Gy0_Rate0']= isset($rate['rate0'])?$rate['rate0']:0;
  267. $param['Gy0_Rate1'] = isset($rate['rate1'])?$rate['rate1']:0;
  268. $param['Mod_rq'] = date('Y-m-d H:i:s',time());
  269. $UniqId = $param['UniqId'];
  270. unset($param['UniqId']);
  271. //修改工艺资料
  272. $sql = \db('工单_工艺资料')->where('UniqId',$UniqId)->fetchSql(true)->update($param);
  273. $res = Db::query($sql);
  274. //获取工艺资料数据
  275. $list = \db('工单_工艺资料')->where('UniqId',$UniqId)->field('Gy0_yjno,Gy0_gxh,rtrim(Gy0_计划接货数) as 计划接货数')->find();
  276. // //修改工单状态
  277. // $status = \db('工单_基本资料')->where('Gd_gdbh',$param['Gy0_gdbh'])->field('rtrim(gd_statu) as status')->find();
  278. // if ($status['status'] !== '2-生产中'){
  279. // $statusSql = \db('工单_基本资料')->where('Gd_gdbh',$param['Gy0_gdbh'])->fetchSql(true)->update(['gd_statu'=>'2-生产中']);
  280. // Db::query($statusSql);
  281. // }
  282. //重新分配工序计划产量
  283. if ((int)$list['计划接货数'] > 0){
  284. $result = $this->PlannedProcessYield($param['Gy0_gdbh'],$list['Gy0_yjno'],$list['Gy0_gxh'],$list['计划接货数']);
  285. }
  286. if ($res !== false){
  287. $this->success('成功');
  288. }else{
  289. $this->error('失败');
  290. }
  291. }
  292. /**
  293. * 新增工单->添加工单
  294. * @ApiMethod (POST)
  295. * @param
  296. */
  297. public function WorkOrderAdd()
  298. {
  299. if (Request::instance()->isPost() === false){
  300. $this->error('请求错误');
  301. }
  302. $param = Request::instance()->post();
  303. if (empty($param)){
  304. $this->error('参数错误');
  305. }
  306. $param['Sys_rq'] = date('Y-m-d H:i:s');
  307. $param['gd_statu'] = '1-计划中';
  308. $prefix = substr($param['订单编号'], 0, 2); // e.g., "DC"
  309. $maxOrder = \db('工单_基本资料')
  310. ->where('订单编号', 'like', "{$prefix}%")
  311. ->order('订单编号', 'desc')
  312. ->limit(1)
  313. ->value('订单编号');
  314. if ($maxOrder) {
  315. $numericPart = substr($maxOrder, 2);
  316. $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
  317. $param['订单编号'] = $prefix . $newNumericPart;
  318. } else {
  319. $param['订单编号'] = $param['订单编号'];
  320. }
  321. if ($maxOrder) {
  322. $numericPart = substr($maxOrder, 2);
  323. $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
  324. $param['订单编号'] = $prefix . $newNumericPart;
  325. } else {
  326. $param['订单编号'] = $param['订单编号'];
  327. }
  328. $data = $param;
  329. unset($data['关联订单']);
  330. unset($data['关联面料ID']);
  331. //新增订单插入至工单基本资料
  332. $sql = \db('工单_基本资料')->fetchSql(true)->insert($data);
  333. \db()->query($sql);
  334. if (!empty($param['关联订单']) && !empty($param['关联面料ID'])){
  335. //关联订单编号
  336. $OrderId = $param['关联订单'];
  337. $OrderNumber = explode(',',$OrderId);
  338. //关联面料ID
  339. $RelevanceId = $param['关联面料ID'];
  340. //查询订单BOM资料,面料资料
  341. $RelevanceList = explode(',',$RelevanceId);
  342. $FabricList = $BomList = $MaterielList = [];
  343. foreach ($RelevanceList as $item){
  344. //工单面料信息
  345. $Fabric = \db('工单_面料资料')
  346. ->where('UNIQID',$item)
  347. ->where('Mod_rq',null)
  348. ->field('BOM_工单编号,BOM_颜色,BOM_物料编码,BOM_物料名称,BOM_投料单位,BOM_计划门幅,BOM_定额门幅')
  349. ->find();
  350. $OrderData = $Fabric;
  351. $OrderData['BOM_工单编号'] = $param['订单编号'];
  352. $OrderData['Sys_ID'] = $param['Sys_id'];
  353. $OrderData['Sys_rq'] = date('Y-m-d H:i:s',time());
  354. $OrderData['BOM_desc'] = $param['要求'];
  355. array_push($FabricList,$OrderData);
  356. //关联订单
  357. $AssociatedNumber = \db('工单关联表')
  358. ->where('订单编号',$Fabric['BOM_工单编号'])
  359. ->where('颜色',$Fabric['BOM_颜色'])
  360. ->where('物料编号',$Fabric['BOM_物料编码'])
  361. ->value('关联编号');
  362. $materiel = [
  363. '关联编号' => $AssociatedNumber,
  364. '订单编号' => $Fabric['BOM_工单编号'],
  365. '生产款号' => $param['生产款号'],
  366. '颜色' => $Fabric['BOM_颜色'],
  367. '物料编号' => $Fabric['BOM_物料编码'],
  368. '物料名称' => $Fabric['BOM_物料名称'],
  369. '备注' => $param['要求'],
  370. 'Sys_id' => $param['Sys_id'],
  371. 'Sys_rq' => date('Y-m-d H:i:s',time()),
  372. ];
  373. array_push($MaterielList,$materiel);
  374. }
  375. foreach ($MaterielList as $index => $item){
  376. $MaterielList[$index]['订单编号'] = $param['订单编号'];
  377. //工单BOM信息
  378. $Bom = \db('工单_bom资料')
  379. ->where('BOM_工单编号',$item['订单编号'])
  380. ->where('BOM_物料名称',$item['物料名称'])
  381. ->where('Mod_rq',null)
  382. ->find();
  383. unset($Bom['UNIQID']);
  384. unset($Bom['Mod_rq']);
  385. $Bom['Sys_ID'] = $param['Sys_id'];
  386. $Bom['Sys_rq'] = date('Y-m-d H:i:s',time());
  387. if (empty($BomList)){
  388. array_push($BomList,$Bom);
  389. }else{
  390. foreach ($BomList as $value){
  391. if ($value['BOM_工单编号'] !== $Bom['BOM_工单编号'] && $value['BOM_物料名称'] !== $Bom['BOM_物料名称']){
  392. array_push($BomList,$Bom);
  393. }
  394. }
  395. }
  396. }
  397. foreach ($BomList as $key => $value){
  398. $BomList[$key]['BOM_工单编号'] = $param['订单编号'];
  399. }
  400. //插入数据
  401. Db::startTrans();
  402. try {
  403. //BOM表数据插入
  404. $BomSql = \db('工单_bom资料')->fetchSql(true)->insertAll($BomList);
  405. $BomRes = \db()->query($BomSql);
  406. //面料表数据插入
  407. $FabricSql = \db('工单_面料资料')->fetchSql(true)->insertAll($FabricList);
  408. $FabricRes = \db()->query($FabricSql);
  409. //工单关联表数据插入
  410. $materielSql = \db('工单关联表')->fetchSql(true)->insertAll($MaterielList);
  411. $materielRes = \db()->query($materielSql);
  412. //提交数据
  413. Db::commit();
  414. }catch (\Exception $e){
  415. //回滚事务
  416. Db::rollback();
  417. }
  418. }else{
  419. //判断新增时面料是否存在,如果有调用gtp自动生成BOM资料
  420. if (!empty($param['面料'])) {
  421. // 只有面料不为空时,才调用 GdGtpAiOrder 方法
  422. $this->GdGtpAiOrder($param['订单编号']);
  423. }
  424. }
  425. $this->success('成功');
  426. }
  427. /**
  428. * 新增印件资料->印件资料添加
  429. * @return void
  430. * @throws \think\db\exception\BindParamException
  431. * @throws \think\exception\PDOException
  432. */
  433. public function PrintDetailAdd()
  434. {
  435. if (Request::instance()->isPost() === false){
  436. $this->error('请求错误');
  437. }
  438. $param = Request::instance()->post();
  439. if (empty($param)){
  440. $this->error('参数错误');
  441. }
  442. $param['Sys_rq'] = date('Y-m-d H:i:s',time());
  443. $process = [
  444. ['1','仓库出库'],['2','裁剪'],['3','车缝'],['4','后道收样'],['5','大烫'],['6','总检'],['7','包装']
  445. ];
  446. $processDetail = [];
  447. foreach ($process as $key=>$value){
  448. $total = null;
  449. if ($key !== 0){
  450. $total = $param['zdtotal'];
  451. }
  452. $processDetail[$key] = [
  453. '订单编号' => $param['订单编号'],
  454. '子订单编号' => $param['子订单编号'],
  455. '款号' => $param['款号'],
  456. '颜色' => $param['颜色'],
  457. '颜色备注' => $param['颜色备注'],
  458. '工序编号' => $value[0],
  459. '工序名称' => $value[1],
  460. '计划产量' => $total,
  461. 'Sys_id' => $param['Sys_id'],
  462. 'Sys_rq' => $param['Sys_rq']
  463. ];
  464. }
  465. $color = \db('工单_面料资料')
  466. ->where('Bom_工单编号',$param['订单编号'])
  467. ->where('BOM_颜色',$param['颜色备注'])
  468. ->select();
  469. $colorList = [];
  470. if (empty($color)){
  471. $BomList = \db('工单_bom资料')
  472. ->where('BOM_工单编号',$param['订单编号'])
  473. ->where('Mod_rq',null)
  474. ->select();
  475. foreach ($BomList as $key=>$value){
  476. $colorList[$key] = [
  477. 'BOM_工单编号' => $param['订单编号'],
  478. 'BOM_颜色' => $param['颜色备注'],
  479. 'BOM_物料编码' => $param['款号'].'-'.$param['颜色备注'].($key+1),
  480. 'BOM_物料名称' => $value['BOM_物料名称'],
  481. 'BOM_投料单位' => '米',
  482. 'Sys_ID' => $param['Sys_id'],
  483. 'Sys_rq' => date('Y-m-d H:i:s',time()),
  484. 'BOM_desc' => $value['BOM_desc']
  485. ];
  486. }
  487. }
  488. //获取最新的关联编号
  489. $AssociatedNumber = \db('工单关联表')->order('关联编号 desc')->column('关联编号');
  490. if (empty($AssociatedNumber)){
  491. $number = 0;
  492. }else{
  493. $number = (int)substr($AssociatedNumber[0],3);
  494. }
  495. $MaterielList = [];
  496. //插入工单关联数据表
  497. foreach ($colorList as $key=>$value){
  498. $MaterielList[$key] = [
  499. '关联编号' => 'GDGL'.($number + $key + 1),
  500. '订单编号' => $value['BOM_工单编号'],
  501. '生产款号' => $param['款号'],
  502. '颜色' => $param['颜色备注'],
  503. '物料编号' => $value['BOM_物料编码'],
  504. '物料名称' => $value['BOM_物料名称'],
  505. '备注' => $value['BOM_desc'],
  506. 'Sys_id' => $param['Sys_id'],
  507. 'Sys_rq' => date('Y-m-d H:i:s',time())
  508. ];
  509. }
  510. //开启事务
  511. db()->startTrans();
  512. try{
  513. //工单颜色录入
  514. $priSql = \db('工单_印件资料')->fetchSql(true)->insert($param);
  515. $priRes = \db()->query($priSql);
  516. //工单工艺录入
  517. $proSql = \db('工单_工艺资料')->fetchSql(true)->insertAll($processDetail);
  518. $proRes = \db()->query($proSql);
  519. //工单面料录入
  520. $fabricSql = \db('工单_面料资料')->fetchSql(true)->insertAll($colorList);
  521. $fabricRes = \db()->query($fabricSql);
  522. //工单关联表录入
  523. $meterieSql = \db('工单关联表')->fetchSql(true)->insertAll($MaterielList);
  524. $meterieRes = \db()->query($meterieSql);
  525. // 提交事务
  526. db()->commit();
  527. } catch (\Exception $e) {
  528. // 回滚事务
  529. db()->rollback();
  530. $this->error($e->getMessage());
  531. }
  532. if ($priRes !== false && $proRes !== false){
  533. $this->success('成功');
  534. }else{
  535. $this->error('失败');
  536. }
  537. }
  538. /**
  539. * 子订单列表
  540. * @return null
  541. * @throws \think\db\exception\DataNotFoundException
  542. * @throws \think\db\exception\ModelNotFoundException
  543. * @throws \think\exception\DbException
  544. */
  545. public function PrintListData()
  546. {
  547. // 检查请求方式
  548. if ($this->request->isGet() === false) {
  549. $this->error('请求错误');
  550. }
  551. $param = $this->request->param();
  552. // 检查参数是否存在
  553. if (isset($param) === false) {
  554. $this->error('参数错误');
  555. }
  556. // 查询型号
  557. $where['Mod_rq'] = null;
  558. $xhdata = \db('工单_印件资料')
  559. ->where('订单编号', $param['order'])
  560. ->where($where)
  561. ->field('cm1,cm2,cm3,cm4,cm5,cm6,cm7,cm8,cm9,cm10')
  562. ->select();
  563. $arr = [];
  564. // 收集cm1到cm10的非空非null值
  565. foreach ($xhdata as $key => $value) {
  566. for ($i = 1; $i <= 10; $i++) {
  567. if ($value['cm' . $i] !== '' && $value['cm' . $i] !== null) {
  568. array_push($arr, $value['cm' . $i]);
  569. }
  570. }
  571. }
  572. $arr = array_unique($arr);
  573. sort($arr);
  574. // 查询详细列表
  575. $list = \db('工单_印件资料')
  576. ->where('订单编号', $param['order'])
  577. ->where($where)
  578. ->field('订单编号,子订单编号,款号,颜色,船样,zdtotal,Sys_id,Sys_rq,ck_rq,sc_rq,cm1,cm2,cm3,cm4,cm5,cm6,updatatime as 更新时间,颜色备注,color_id,cm7,cm8,cm9,cm10,cmsl1,cmsl2,cmsl3,cmsl4,cmsl5,cmsl6,cmsl7,cmsl8,cmsl9,cmsl10,Uniqid')
  579. ->select();
  580. // 遍历列表并处理cm和cmsl字段
  581. foreach ($list as $key => $value) {
  582. for ($i = 1; $i <= 10; $i++) {
  583. if ($value['cm' . $i] !== '') {
  584. // 如果 cmsl 的值为 0,则设置为空字符串
  585. $list[$key][$value['cm' . $i]] = ($value['cmsl' . $i] === 0) ? '' : $value['cmsl' . $i];
  586. }
  587. // 删除原有的 cm 和 cmsl 字段
  588. // unset($list[$key]['cm' . $i], $list[$key]['cmsl' . $i]);
  589. }
  590. }
  591. // 自定义型号排序
  592. $customOrder = array('XXS','XS','S', 'M', 'L', 'XL','XXL', 'XXXL', 'XXXXL', '2XL', '3XL', '4XL');
  593. usort($arr, function ($a, $b) use ($customOrder) {
  594. $posA = array_search($a, $customOrder);
  595. $posB = array_search($b, $customOrder);
  596. return $posA - $posB;
  597. });
  598. // 返回结果
  599. $data['型号'] = $arr;
  600. $data['列表'] = $list;
  601. $this->success('成功', $data);
  602. }
  603. /**
  604. * 工单资料管理->印件资料删除
  605. * @return void
  606. * @throws \think\Exception
  607. * @throws \think\exception\PDOException
  608. */
  609. public function PrintDetailDel()
  610. {
  611. if ($this->request->isGet() === false){
  612. $this->error('请求错误');
  613. }
  614. $param = $this->request->param();
  615. if (isset($param['UniqId']) === false){
  616. $this->error('参数错误');
  617. }
  618. $printId = explode(',',$param['UniqId']);
  619. $i = 0;
  620. foreach ($printId as $value){
  621. $res = \db('工单_印件资料')
  622. ->where('Uniqid',$value)
  623. ->update(['Mod_rq'=>date('Y-m-d H:i:s',time())]);
  624. if ($res === false){
  625. $i++;
  626. }
  627. }
  628. if ($i === 0){
  629. $this->success('删除成功');
  630. }else{
  631. $this->error('删除失败');
  632. }
  633. }
  634. /**
  635. * 月度车间报工汇总->报工删除记录
  636. */
  637. public function ProcessDetailDel()
  638. {
  639. if ($this->request->isGet() === false){
  640. $this->error('请求错误');
  641. }
  642. $param = $this->request->param();
  643. if (empty($param)) {
  644. $this->error('参数错误');
  645. }
  646. $where['a.mod_rq'] = ['neq', ''];
  647. $list = \db('设备_产量计酬')->alias('a')
  648. ->join('工单_印件资料 b', 'b.订单编号 = a.订单编号 AND a.子订单编号 = a.子订单编号')
  649. ->join('工单_基本资料 j', 'b.订单编号 = j.订单编号', 'LEFT')
  650. ->field('
  651. b.订单编号, b.子订单编号, b.款号, b.颜色, b.船样, a.尺码, b.zdtotal as 制单数,b.颜色备注,
  652. a.数量, a.sys_rq as 上报时间,a.UniqId,a.mod_rq,a.delsys_id,a.sczl_bh,
  653. j.客户编号,j.生产款号,j.款式
  654. ')
  655. ->where($where)
  656. ->order('a.mod_rq desc')
  657. ->limit($param['page'],$param['limit'])
  658. ->group('a.UniqId')
  659. ->select();
  660. $count = \db('设备_产量计酬')->alias('a')
  661. ->join('工单_印件资料 b', 'b.订单编号 = a.订单编号 AND a.子订单编号 = a.子订单编号')
  662. ->join('工单_基本资料 j', 'b.订单编号 = j.订单编号', 'LEFT')
  663. ->field('
  664. b.订单编号, b.子订单编号, b.款号, b.颜色, b.船样, a.尺码, b.zdtotal as 制单数,b.颜色备注,
  665. a.数量, a.sys_rq as 上报时间,a.UniqId,a.mod_rq,a.delsys_id,a.sczl_bh,
  666. j.客户编号,j.生产款号,j.款式
  667. ')
  668. ->where($where)
  669. ->order('a.mod_rq desc')
  670. ->group('a.UniqId')
  671. ->select();
  672. // 提取所有的尺码,并去重
  673. $sizeList = array_values(array_unique(array_column($list, '尺码')));
  674. // 动态将尺码的数量添加到每个订单中,并替换已完成字段
  675. foreach ($list as &$item) {
  676. $size = $item['尺码'];
  677. $item[$size] = $item['数量']; // 动态添加尺码字段,值为数量
  678. // unset($item['数量']); // 移除原来的已完成字段
  679. }
  680. $data['total'] = count($count);
  681. $data['table'] = $list;
  682. $this->success('成功',$data);
  683. }
  684. /**
  685. * 产品附件新增
  686. * 1.前端进行上传xlsx文件表格
  687. * 2.接口接受数据文件进行保存xlsx文件以及pdf转换
  688. * 3.前端进行预览pdf图片显示文件中的内容再页面上
  689. */
  690. public function gdAnnexAdd() {
  691. ini_set('display_errors', 'On');
  692. ini_set('error_reporting', E_ALL);
  693. if (!$this->request->isPost()) {
  694. $this->error('请求方式错误');
  695. }
  696. // 获取请求参数
  697. $req = $this->request->param();
  698. $relateId = $req['关联编号'];
  699. $attachmentContent = $req['附件内容'];
  700. $attachmentType = $req['附件类型'];
  701. $prefixDir = ROOT_PATH . '/public/';
  702. $uploadDir = ''.'uploads/' . date('Ymd') . '/' . $relateId;
  703. DB::name('工单_基本资料')
  704. ->where('订单编号', $relateId)
  705. ->update(['gd_statu' => '2-生产中']);
  706. // 检查并创建目录
  707. if (!is_dir($prefixDir . $uploadDir)) {
  708. mkdir($prefixDir . $uploadDir, 0777, true);
  709. }
  710. // 处理 Base64 附件内容
  711. if (strpos($attachmentContent, 'base64,') !== false) {
  712. $attachmentContent = explode('base64,', $attachmentContent)[1];
  713. }
  714. $fileContent = base64_decode($attachmentContent);
  715. $filename = time();
  716. // 初始化文件路径变量
  717. $xlsxFilePath = '';
  718. $pdfFilePath = '';
  719. if ($attachmentType === 'pdf') {
  720. // 保存 PDF 文件
  721. $pdfFilePath = $uploadDir . '/' . $filename . '.pdf';
  722. file_put_contents($prefixDir . $pdfFilePath, $fileContent);
  723. } elseif ($attachmentType === 'xlsx') {
  724. // 保存 Excel 文件
  725. $xlsxFilePath = $uploadDir . '/' . $filename . '.xlsx';
  726. file_put_contents($prefixDir . $xlsxFilePath, $fileContent);
  727. // 转换为 PDF 文件
  728. $pdfFilePath = $uploadDir . '/' . $filename . '.pdf';
  729. $cmd = sprintf(
  730. 'libreoffice --headless --convert-to pdf --outdir %s %s',
  731. escapeshellarg($prefixDir . $uploadDir),
  732. escapeshellarg($prefixDir . $xlsxFilePath)
  733. );
  734. exec($cmd, $out, $retval);
  735. if ($retval !== 0) {
  736. $this->error('Excel 转 PDF 失败');
  737. }
  738. } else {
  739. $this->error('不支持的附件类型');
  740. }
  741. // 组织数据
  742. $data = [
  743. '关联编号' => $relateId,
  744. 'sys_id' => $req['sys_id'],
  745. '附件备注' => $req['附件备注'],
  746. '附件类型' => $attachmentType,
  747. 'sys_rq' => date('Y-m-d H:i:s'),
  748. 'url' => $xlsxFilePath, // 保存 xlsx 文件路径(如果存在)
  749. 'pdf' => $pdfFilePath // 保存 pdf 文件路径
  750. ];
  751. // 数据库事务处理
  752. db()->startTrans();
  753. try {
  754. // 插入数据
  755. $sql = db('工单_相关附件')->fetchSql(true)->insert($data);
  756. $result = db()->query($sql);
  757. db()->commit();
  758. } catch (\Exception $e) {
  759. // 回滚事务
  760. db()->rollback();
  761. $this->error($e->getMessage());
  762. }
  763. if ($result === false) {
  764. $this->error('失败');
  765. }
  766. $this->success('成功');
  767. }
  768. /**
  769. * 订单打印接口
  770. * order:订单编号
  771. * 通过订单编号获取订单表数据以及子订单数据
  772. */
  773. public function orderPrint(){
  774. if ($this->request->isGet() === false){$this->error('请求错误');}
  775. $param = $this->request->param();
  776. if (empty($param['order'])){$this->error('参数错误');}
  777. $where['Mod_rq'] = null;
  778. //订单信息
  779. $list = \db('工单_基本资料')
  780. ->where('订单编号',$param['order'])
  781. ->where($where)
  782. ->field('订单编号,img,生产款号,客户编号,款式,落货日期,箱唛要求,面料,船样描述,船样合计,粘衬,订单数量,审核,审核日期,要求,water')
  783. ->find();
  784. //尺码表格表头
  785. $xhdata = \db('工单_印件资料')->where('订单编号', $param['order'])->where($where)->select();
  786. $arr = [];
  787. foreach ($xhdata as $key => $value) {
  788. for ($i = 1; $i <= 10; $i++) {
  789. if ($value['cm' . $i] !== '' && $value['cm' . $i] !== null) {
  790. array_push($arr, $value['cm' . $i]);
  791. }
  792. }
  793. }
  794. // 去重并重新索引
  795. $arr = array_unique($arr);
  796. $arr = array_values($arr);
  797. // 自定义排序函数
  798. usort($arr, function($a, $b) {
  799. // 判断是否为数字
  800. $isNumericA = is_numeric($a);
  801. $isNumericB = is_numeric($b);
  802. if ($isNumericA && $isNumericB) {
  803. // 如果都是数字,按从小到大排序
  804. return $a - $b;
  805. } elseif (!$isNumericA && !$isNumericB) {
  806. // 如果都是字母,按字母顺序排序(可以自定义顺序)
  807. $sizeOrder = ['XXS', 'XS', 'S', 'M', 'L', 'XL', 'XXL', 'XXXL','XXXXL'];
  808. $posA = array_search($a, $sizeOrder);
  809. $posB = array_search($b, $sizeOrder);
  810. return $posA - $posB;
  811. } else {
  812. // 如果一个是数字一个是字母,数字排在前
  813. return $isNumericA ? -1 : 1;
  814. }
  815. });
  816. //打印table数据表格
  817. $porlis = \db('工单_印件资料')
  818. ->where('订单编号',$param['order'])
  819. ->where('船样',0)
  820. ->where($where)
  821. ->field('子订单编号')
  822. ->select();
  823. //合并后的子订单条码数据
  824. $subOrder = $porlis[0]['子订单编号'];
  825. // 找到子订单编号中的 '-' 位置
  826. $dashPos = strpos($subOrder, '-');
  827. if ($dashPos !== false) {
  828. // 提取 '-' 后面的部分
  829. $afterDash = substr($subOrder, $dashPos + 1);
  830. // 判断长度是否等于2或等于4
  831. if (strlen($afterDash) == 2) {
  832. // 查询船样为0的数据
  833. $processlist = \db('工单_印件资料')
  834. ->where('订单编号', $param['order'])
  835. ->where($where)
  836. ->where('船样', 0)
  837. ->field('子订单编号,颜色,款号,zdtotal,颜色备注,color_id,
  838. cm1,cm2,cm3,cm4,cm5,cm6,cm7,cm8,cm9,cm10,
  839. cmsl1,cmsl2,cmsl3,cmsl4,cmsl5,cmsl6,cmsl7,cmsl8,cmsl9,cmsl10,Uniqid')
  840. ->select();
  841. // 初始化汇总数组
  842. $scslTotals = [
  843. "cmsl1" => 0,
  844. "cmsl2" => 0,
  845. "cmsl3" => 0,
  846. "cmsl4" => 0,
  847. "cmsl5" => 0,
  848. "cmsl6" => 0,
  849. "cmsl7" => 0,
  850. "cmsl8" => 0,
  851. "cmsl9" => 0,
  852. "cmsl10" => 0,
  853. "zdtotal" => 0, // 总计数量
  854. ];
  855. // 遍历数据集进行汇总
  856. foreach ($processlist as $item) {
  857. // 遍历每个尺码字段(cmsl1 到 cmsl10)
  858. for ($i = 1; $i <= 10; $i++) {
  859. // 获取当前字段的数量
  860. $sizeQty = $item['cmsl' . $i];
  861. // 判断数量是否有效(非空且大于0)
  862. if (!empty($sizeQty)) {
  863. // 累加当前字段的数量
  864. $scslTotals['cmsl' . $i] += $sizeQty;
  865. // 累加到总计字段
  866. $scslTotals['zdtotal'] += $sizeQty;
  867. }
  868. }
  869. }
  870. $data['scslTotals'] = $scslTotals;
  871. foreach ($processlist as $key => $value) {
  872. // 将尺码和对应的数量从 cm1-cm10 和 cmsl1-cmsl10 转换为动态键值对
  873. for ($i = 1; $i <= 10; $i++) {
  874. if ($value['cm' . $i] !== '' && $value['cm' . $i] !== null) {
  875. $processlist[$key][$value['cm' . $i]] = $value['cmsl' . $i];
  876. }
  877. // 移除原始的 cm 和 cmsl 字段
  878. unset($processlist[$key]['cm' . $i], $processlist[$key]['cmsl' . $i]);
  879. }
  880. }
  881. // 用于存储合并后的数据
  882. $mergedData = [];
  883. // 按颜色备注进行合并
  884. foreach ($processlist as $item) {
  885. $key = $item['颜色备注'];
  886. if (!isset($mergedData[$key])) {
  887. $mergedData[$key] = $item;
  888. // 添加条码字段,值为子订单编号
  889. $mergedData[$key]['条码'] = $item['子订单编号'];
  890. } else {
  891. // 合并尺码对应的数量
  892. foreach ($item as $size => $quantity) {
  893. if (is_numeric($size)) {
  894. if (!isset($mergedData[$key][$size])) {
  895. $mergedData[$key][$size] = 0;
  896. }
  897. $mergedData[$key][$size] += $quantity;
  898. }
  899. }
  900. // 合并 zdtotal
  901. $mergedData[$key]['zdtotal'] += $item['zdtotal'];
  902. }
  903. }
  904. // 查询船样为1的数据
  905. $chuanyang = \db('工单_印件资料')
  906. ->where('订单编号', $param['order'])
  907. ->where($where)
  908. ->where('船样', 1)
  909. ->field('子订单编号,颜色,款号,zdtotal,颜色备注,color_id,
  910. cm1,cm2,cm3,cm4,cm5,cm6,cm7,cm8,cm9,cm10,
  911. cmsl1,cmsl2,cmsl3,cmsl4,cmsl5,cmsl6,cmsl7,cmsl8,cmsl9,cmsl10,Uniqid')
  912. ->select();
  913. foreach ($chuanyang as $key => $value) {
  914. // 将尺码和对应的数量从 cm1-cm10 和 cmsl1-cmsl10 转换为动态键值对
  915. for ($i = 1; $i <= 10; $i++) {
  916. if ($value['cm' . $i] !== '' && $value['cm' . $i] !== null) {
  917. $chuanyang[$key][$value['cm' . $i]] = $value['cmsl' . $i];
  918. }
  919. // 移除原始的 cm 和 cmsl 字段
  920. unset($chuanyang[$key]['cm' . $i], $chuanyang[$key]['cmsl' . $i]);
  921. }
  922. // 添加条码字段,值为子订单编号
  923. $chuanyang[$key]['条码'] = $value['子订单编号'];
  924. }
  925. // 将合并后的数据插入到相应颜色备注的原始数据尾部
  926. $finalList = [];
  927. $groupedData = [];
  928. // 将原始数据按颜色备注分组
  929. foreach ($processlist as $item) {
  930. $key = $item['颜色备注'];
  931. if (!isset($groupedData[$key])) {
  932. $groupedData[$key] = [];
  933. }
  934. $groupedData[$key][] = $item;
  935. }
  936. // 将合并后的数据插入到对应的颜色备注组的尾部
  937. foreach ($groupedData as $key => $items) {
  938. $finalList = array_merge($finalList, $items); // 先添加原始数据
  939. if (isset($mergedData[$key])) {
  940. $finalList[] = $mergedData[$key]; // 在组的尾部添加合并数据
  941. }
  942. }
  943. // 将船样为1的数据添加到最终列表中
  944. $finalList = array_merge($finalList, $chuanyang);
  945. $data['process'] = $finalList;
  946. $data['order'] = $list;
  947. $data['xhdata'] = $arr;
  948. $this->success('成功',$data);
  949. } elseif (strlen($afterDash) == 4) {
  950. //一条子订单编号一个条码,统计颜色
  951. // $processlist = \db('工单_印件资料')
  952. // ->where('订单编号', $param['order'])
  953. // ->whereNull('Mod_rq') // 查询未删除数据
  954. // ->select();
  955. //
  956. // $table = [];
  957. // foreach ($processlist as $item) {
  958. // // 当前子订单编号的数据
  959. // $subOrder = [
  960. // '颜色备注' => $item['颜色备注'],
  961. // '色系名称' => $item['颜色'],
  962. // '订单编号' => $item['订单编号'],
  963. // '子订单编号' => $item['子订单编号'],
  964. // '条码' => $item['子订单编号'],
  965. // '款号' => $item['款号'],
  966. // ];
  967. // // 当前子订单编号的合计
  968. // $subOrderTotal = 0;
  969. // for ($i = 1; $i <= 10; $i++) {
  970. // if (!empty($item['cm' . $i])) {
  971. // $subOrder[$item['cm' . $i]] = $item['cmsl' . $i];
  972. // // 累加每个尺码的数量
  973. // $subOrderTotal += $item['cmsl' . $i];
  974. // }
  975. // unset($item['cm' . $i], $item['cmsl' . $i]);
  976. // }
  977. // $subOrder['合计'] = $subOrderTotal; // 添加合计
  978. // $table[] = $subOrder; // 将当前子订单的数据添加到 $table 中
  979. // }
  980. $processlist = \db('工单_印件资料')
  981. ->where('订单编号', $param['order'])
  982. ->whereNull('Mod_rq') // 查询未删除数据
  983. ->select();
  984. $table = [];
  985. foreach ($processlist as $item) {
  986. // 当前子订单编号的数据
  987. $subOrder = [
  988. '颜色备注' => $item['颜色备注'],
  989. '色系名称' => $item['颜色'],
  990. '订单编号' => $item['订单编号'],
  991. '子订单编号' => $item['子订单编号'],
  992. '条码' => $item['子订单编号'],
  993. '款号' => $item['款号'],
  994. ];
  995. // 当前子订单编号的合计
  996. $subOrderTotal = 0;
  997. for ($i = 1; $i <= 10; $i++) {
  998. // 判断 cm 和 cmsl 是否有值,空值不显示,0 则显示
  999. if (isset($item['cm' . $i]) && $item['cm' . $i] !== '') {
  1000. $subOrder[$item['cm' . $i]] = $item['cmsl' . $i] ?? 0; // 默认数量为 0
  1001. // 累加每个尺码的数量
  1002. $subOrderTotal += (int)$item['cmsl' . $i]; // 确保是数值类型
  1003. }
  1004. // 清理字段
  1005. unset($item['cm' . $i], $item['cmsl' . $i]);
  1006. }
  1007. $subOrder['合计'] = $subOrderTotal; // 添加合计
  1008. $table[] = $subOrder; // 将当前子订单的数据添加到 $table 中
  1009. }
  1010. // 初始化汇总数组
  1011. $scslTotals = [
  1012. "cmsl1" => 0,
  1013. "cmsl2" => 0,
  1014. "cmsl3" => 0,
  1015. "cmsl4" => 0,
  1016. "cmsl5" => 0,
  1017. "cmsl6" => 0,
  1018. "cmsl7" => 0,
  1019. "cmsl8" => 0,
  1020. "cmsl9" => 0,
  1021. "cmsl10" => 0,
  1022. "zdtotal" => 0, // 总计数量
  1023. ];
  1024. // 遍历数据集进行汇总
  1025. foreach ($processlist as $item) {
  1026. // 遍历每个尺码字段(cmsl1 到 cmsl10)
  1027. for ($i = 1; $i <= 10; $i++) {
  1028. // 获取当前字段的数量
  1029. $sizeQty = $item['cmsl' . $i];
  1030. // 判断数量是否有效(非空且大于0)
  1031. if (!empty($sizeQty)) {
  1032. // 累加当前字段的数量
  1033. $scslTotals['cmsl' . $i] += $sizeQty;
  1034. // 累加到总计字段
  1035. $scslTotals['zdtotal'] += $sizeQty;
  1036. }
  1037. }
  1038. }
  1039. $data['scslTotals'] = $scslTotals;
  1040. $data['process'] = $table;//汇总数据集
  1041. $data['order'] = $list;//表格数据
  1042. $data['xhdata'] = $arr;//尺码表头
  1043. $this->success('成功', $data);
  1044. // }
  1045. } else {
  1046. echo "子订单编号 - 后不是2位也不是4位:$afterDash";
  1047. }
  1048. } else {
  1049. echo "子订单编号中没有找到'-'";
  1050. }
  1051. }
  1052. /**
  1053. * 订单编号自动获取
  1054. * @return void
  1055. * @throws \think\db\exception\DataNotFoundException
  1056. * @throws \think\db\exception\ModelNotFoundException
  1057. * @throws \think\exception\DbException
  1058. */
  1059. public function getWorkOrder()
  1060. {
  1061. if ($this->request->isGet() === false){
  1062. $this->error('请求错误');
  1063. }
  1064. $time =substr( date('Ym',time()),2);
  1065. $lastOrder = \db('工单_基本资料')
  1066. ->where('订单编号','like','%'.$time.'%')
  1067. ->order('Uniqid desc')
  1068. ->find();
  1069. if (empty($lastOrder)){
  1070. $newNumber = 1;
  1071. }else{
  1072. $lastNumber = substr($lastOrder['订单编号'],6);
  1073. $newNumber = (int)$lastNumber + 1;
  1074. }
  1075. if ($newNumber<10){
  1076. $newOrder = 'DC'.$time.'00'.$newNumber;
  1077. }elseif ($newNumber>=10 && $newNumber<100){
  1078. $newOrder = 'DC'.$time.'0'.$newNumber;
  1079. }else{
  1080. $newOrder = 'DC'.$time.$newNumber;
  1081. }
  1082. $this->success('成功',$newOrder);
  1083. }
  1084. /**
  1085. * 获取子订单编号
  1086. * @return void
  1087. * @throws \think\db\exception\DataNotFoundException
  1088. * @throws \think\db\exception\ModelNotFoundException
  1089. * @throws \think\exception\DbException
  1090. */
  1091. public function getSuborder(){
  1092. // 确保是GET请求
  1093. if ($this->request->isGet() === false) {
  1094. $this->error('请求错误');
  1095. }
  1096. $param = $this->request->param();
  1097. if (empty($param) || !isset($param['cy']) || !isset($param['order'])) {
  1098. $this->error('参数错误');
  1099. }
  1100. // 判断是否“船样”获取对应的子订单编号
  1101. if ($param['cy'] == '否') {
  1102. //1.通过色系名称查询对应的编号
  1103. $colorlist = \db('工单_颜色编号')
  1104. ->field('colorcode, colorname')
  1105. ->where('colorname', $param['colorname'] ?? '')
  1106. ->find();
  1107. if (empty($colorlist)) {
  1108. $this->error('未找到对应的颜色编号');
  1109. }
  1110. $num = $param['order'] . '-' . $colorlist['colorcode'];
  1111. // 查询子订单编号
  1112. $data = \db('工单_印件资料')
  1113. ->field('子订单编号,cm1,cm2,cm3,cm4,cm5,cm6,cm7,cm8,cm9,cm10')
  1114. ->where('子订单编号', 'like', '%' . $num . '%')
  1115. ->where('船样', '=', 0)
  1116. ->order('子订单编号', 'desc')
  1117. ->find();
  1118. if (empty($data)) {
  1119. // 如果没有找到数据,生成默认的订单编号,后两位从00开始
  1120. $order = $param['order'] . '-' . $colorlist['colorcode'] . '00';
  1121. } else {
  1122. if (strlen($data['子订单编号']) == 12) {
  1123. $data = \db('工单_印件资料')
  1124. ->where('订单编号',$param['order'])
  1125. ->where('船样',0)
  1126. ->order('子订单编号 desc')
  1127. ->find();
  1128. if(empty($data)){
  1129. $order = $param['order'].'-01';
  1130. }else{
  1131. $num = (int)substr($data['子订单编号'],10) + 1;
  1132. if ($num<10){
  1133. $order = $param['order'].'-0'.$num;
  1134. }else{
  1135. $order = $param['order'].'-'.$num;
  1136. }
  1137. }
  1138. }else{
  1139. // 如果找到数据,提取子订单编号并递增
  1140. $order = $data['子订单编号'];
  1141. if (preg_match('/(.*-' . $colorlist['colorcode'] . ')(\d{2})$/', $order, $matches)) {
  1142. $prefix = $matches[1]; // 前缀部分(包括订单编号和颜色代码)
  1143. $number = $matches[2]; // 数字部分(后两位)
  1144. // 循环生成子订单编号并检查数据库中是否存在相同编号
  1145. do {
  1146. $incrementedNumber = (int)$number + 1;
  1147. // 将数字部分补充为两位数,例如 1 -> 01,2 -> 02
  1148. $order = $prefix . str_pad($incrementedNumber, 2, '0', STR_PAD_LEFT);
  1149. $exists = \db('工单_印件资料')->where('子订单编号', '=', $order)->find();
  1150. $number = $incrementedNumber; // 更新 number 用于下一次循环
  1151. } while ($exists); // 如果存在相同编号则继续循环递增
  1152. } else {
  1153. $this->error('订单编号格式错误');
  1154. }
  1155. }
  1156. }
  1157. //2.获取色系名称信息
  1158. $colorlist = \db('工单_颜色编号')->select();
  1159. //3.获取历史尺码数据
  1160. $cm_list = \db('工单_印件资料')
  1161. ->where('订单编号', $param['order'])
  1162. ->group('订单编号')
  1163. ->find();
  1164. $cm_data = [];
  1165. if ($cm_list) {
  1166. // 精准筛选字段名以 "cm" 开头并跟1到2位数字的字段
  1167. foreach ($cm_list as $key => $value) {
  1168. if (preg_match('/^cm\d{1,2}$/', $key)) {
  1169. $cm_data[$key] = $value ?? ''; // 如果值为 null,设为空字符串
  1170. }
  1171. }
  1172. } else {
  1173. // 如果查询结果为空,将 cm1 到 cm10 都设置为空
  1174. for ($i = 1; $i <= 10; $i++) {
  1175. $cm_data["cm$i"] = '';
  1176. }
  1177. }
  1178. $result = ['order' => $order,'colorlist' => $colorlist,'cm' => $cm_data];
  1179. $this->success('成功', $result);
  1180. } else if ($param['cy'] == '是') {
  1181. //1.获取船样子订单编号
  1182. $data = \db('工单_印件资料')
  1183. ->where('订单编号', $param['order'])
  1184. ->where('船样', '=', 1)
  1185. ->order('子订单编号 asc')
  1186. ->find();
  1187. if (empty($data)) {
  1188. // 如果没有数据,初始子订单编号为 '99'
  1189. $order = $param['order'] . '-99';
  1190. } else {
  1191. // 提取子订单编号中的数字部分
  1192. $subOrder = $data['子订单编号']; // 例如 "DC2410006-99"
  1193. if (preg_match('/-(\d+)$/', $subOrder, $matches)) {
  1194. $numberPart = (int)$matches[1]; // 提取到的数字部分
  1195. $newNumber = $numberPart - 1; // 减 1
  1196. // 将新的数字拼接回订单编号
  1197. $order = preg_replace('/-\d+$/', '-' . $newNumber, $subOrder);
  1198. } else {
  1199. $this->error('订单编号格式错误');
  1200. }
  1201. }
  1202. $this->success('成功', $order);
  1203. }
  1204. }
  1205. /**
  1206. * 获取PO号 【代码展示未用到】
  1207. */
  1208. public function getPonumber() {
  1209. if ($this->request->isGet() === false){
  1210. $this->error('请求错误');
  1211. }
  1212. $param = $this->request->param();
  1213. if (empty($param)){
  1214. $this->error('参数错误');
  1215. }
  1216. // $num = substr($param['child_order'], 0, 12); // 如果需要,可以用这个方式截取子订单编号
  1217. // $sql = "SELECT * FROM `工单_印件资料` WHERE `子订单编号` LIKE '{$num}%' ORDER BY `子订单编号` DESC LIMIT 1";
  1218. // $data = \db()->query($sql);
  1219. $colorlist = \db('工单_颜色编号')
  1220. ->field('colorcode,colorname')
  1221. ->where('colorname',$param['child_order'])
  1222. ->find();
  1223. $num = $param['order'] . '-' . $colorlist['colorcode']; // 生成 num,用于模糊查询
  1224. $data = \db('工单_印件资料')
  1225. ->where('子订单编号', 'like', '%' . $num . '%')
  1226. ->order('子订单编号', 'desc')
  1227. ->find();
  1228. if(count($data) === 1){
  1229. $order = $num.'01';
  1230. }else{
  1231. $number = (int)substr($data['子订单编号'],12,14) + 1;
  1232. if ($num<10){
  1233. $order = $num.'0'.$number;
  1234. }else{
  1235. $order = $num.$number;
  1236. }
  1237. }
  1238. $this->success('成功',$order);
  1239. }
  1240. /**
  1241. * 订单资料修改
  1242. * @return void
  1243. * @throws \think\Exception
  1244. * @throws \think\db\exception\BindParamException
  1245. * @throws \think\exception\PDOException
  1246. */
  1247. public function WorkOrderEdit()
  1248. {
  1249. if (Request::instance()->isPost() === false){
  1250. $this->error('请求错误');
  1251. }
  1252. $param = Request::instance()->post();
  1253. if (empty($param)){
  1254. $this->error('参数错误');
  1255. }
  1256. $id = $param['id'];
  1257. unset($param['id']);
  1258. $sql = \db('工单_基本资料')
  1259. ->where('Uniqid',$id)
  1260. ->fetchSql(true)
  1261. ->update($param);
  1262. $res = \db()->query($sql);
  1263. if ($res === false){
  1264. $this->error('失败');
  1265. }else{
  1266. $this->success('成功');
  1267. }
  1268. }
  1269. /**
  1270. * 颜色资料修改
  1271. * @return void
  1272. * @throws \think\Exception
  1273. * @throws \think\db\exception\BindParamException
  1274. * @throws \think\exception\PDOException
  1275. */
  1276. public function PrintDataEdit()
  1277. {
  1278. if(Request::instance()->post() === false){
  1279. $this->error('请求错误');
  1280. }
  1281. $param = Request::instance()->post();
  1282. if (empty($param)){
  1283. $this->error('参数错误');
  1284. }
  1285. $updata = [
  1286. '订单编号' => $param['订单编号'],
  1287. '子订单编号' => $param['子订单编号'],
  1288. '款号' => $param['款号'],
  1289. '船样' => $param['船样'],
  1290. '颜色' => $param['颜色'],
  1291. 'color_id' => $param['color_id'],
  1292. '颜色备注' => $param['颜色备注'],
  1293. 'zdtotal' => $param['zdtotal']
  1294. ];
  1295. for ($i = 1; $i <= 10; $i++) {
  1296. $updata["cmsl{$i}"] = isset($param["cmsl{$i}"]) ? $param["cmsl{$i}"] : '';
  1297. }
  1298. $sql = \db('工单_印件资料')
  1299. ->where('Uniqid', $param['id'])
  1300. ->fetchSql(true)
  1301. ->update($updata);
  1302. $res = \db()->query($sql);
  1303. if ($res !== false) {
  1304. $this->success('修改成功');
  1305. } else {
  1306. $this->error('修改失败');
  1307. }
  1308. }
  1309. /**
  1310. * 图片上传
  1311. * @return void
  1312. */
  1313. public function ImgUpload(){
  1314. $file = request()->file('image');
  1315. if($file){
  1316. $info = $file->validate(['size'=>10485760,'ext'=>'jpg,png'])->move(ROOT_PATH . 'public' . DS . 'uploads');
  1317. if($info){
  1318. $fileName = $info->getSaveName();
  1319. // $ymd = date('Ymd');
  1320. // $imageUrl = '/uploads/' . $ymd.'/'.$fileName;
  1321. $imageUrl = '/uploads/' . str_replace('\\', '/', $fileName);
  1322. return json(['code' => 0, 'msg' => '成功', 'data' => ['url' => $imageUrl]]);
  1323. }else{
  1324. $res = $file->getError();
  1325. return json(['code' => 1, 'msg' => '失败', 'data' => $res]);
  1326. }
  1327. }
  1328. return json(['code' => 1, 'msg' => '没有文件上传', 'data' => null]);
  1329. }
  1330. /**
  1331. * 工单技术附件
  1332. * @return void
  1333. * @throws \think\db\exception\DataNotFoundException
  1334. * @throws \think\db\exception\ModelNotFoundException
  1335. * @throws \think\exception\DbException
  1336. */
  1337. public function OrderAttachments()
  1338. {
  1339. if ($this->request->isGet() === false){
  1340. $this->error('请求错误');
  1341. }
  1342. $param = $this->request->param();
  1343. if (empty($param)){
  1344. $this->error('参数错误');
  1345. }
  1346. $list = \db('工单_相关附件')
  1347. ->where('关联编号',$param['order'])
  1348. ->where('附件备注',$param['desc'])
  1349. ->whereNull('Mod_rq')
  1350. ->order('sys_rq desc')
  1351. ->limit(1)
  1352. ->select();
  1353. $this->success('成功',$list);
  1354. }
  1355. /**
  1356. * 订单BOM资料显示
  1357. * @return void
  1358. * @throws \think\db\exception\DataNotFoundException
  1359. * @throws \think\db\exception\ModelNotFoundException
  1360. * @throws \think\exception\DbException
  1361. */
  1362. public function OrderBomList()
  1363. {
  1364. if ($this->request->isGet() === false){
  1365. $this->error('请求错误');
  1366. }
  1367. $param = $this->request->param();
  1368. if (empty($param) || !isset($param['order'])){
  1369. $this->error('参数错误');
  1370. }
  1371. $where = ['a.BOM_工单编号'=>$param['order']];
  1372. $list = \db('工单_bom资料')
  1373. ->alias('a')
  1374. ->join('工单_基本资料 b','b.订单编号 = a.BOM_工单编号')
  1375. ->field('a.BOM_工单编号 as 订单编号,b.生产款号 as 生产款号,b.客户编号 as 客户编号,b.款式 as 款式,
  1376. a.BOM_物料名称 as 物料名称,a.BOM_投料单位 as 投料单位,a.BOM_计划用量 as 计划用料,a.BOM_标准用量 as 定额用料,
  1377. a.BOM_实际用量 as 裁床实际用料,a.BOM_desc as 备注,a.UNIQID,
  1378. a.BOM_计划门幅 as 计划门幅, a.BOM_定额门幅 as 定额门幅,a.Sys_ID as ID,a.Sys_rq as 日期')
  1379. ->where($where)
  1380. ->whereNull('a.Mod_rq')
  1381. ->select();
  1382. if (!empty($list)) {
  1383. $this->success('成功', $list);
  1384. } else {
  1385. // 调用其他方法处理逻辑(例如记录日志、执行其他操作等)
  1386. $this->GdGtpAiOrder($param['order']);
  1387. // 返回空数据的统一处理
  1388. return $this->success('没有找到相关数据', []);
  1389. }
  1390. }
  1391. /**
  1392. * Bom资料删除
  1393. * */
  1394. public function Bomdel()
  1395. {
  1396. if ($this->request->isGet() === false) {
  1397. $this->error('请求错误');
  1398. }
  1399. // 获取请求参数
  1400. $param = $this->request->param();
  1401. // 检查参数是否为空或者缺少UNIQID
  1402. if (empty($param) || !isset($param['UNIQID'])) {
  1403. $this->error('参数错误');
  1404. }
  1405. // 判断UNIQID是否是逗号分隔的多个ID,如果是则拆分成数组,否则直接处理为单个ID
  1406. $uniqids = strpos($param['UNIQID'], ',') !== false ? explode(',', $param['UNIQID']) : [$param['UNIQID']];
  1407. $where = [];
  1408. $where['Mod_rq'] = date('Y-m-d H:i:s', time());
  1409. // 定义一个标志变量来追踪是否所有更新都成功
  1410. $allUpdated = true;
  1411. $failedUniqids = [];
  1412. // 遍历所有UNIQID并更新数据库
  1413. foreach ($uniqids as $uniqid) {
  1414. // 更新指定UNIQID的记录
  1415. $result = \db('工单_bom资料')
  1416. ->where('UNIQID', $uniqid)
  1417. ->update($where);
  1418. // 检查更新结果
  1419. if (!$result) {
  1420. // 如果某个UNIQID更新失败,记录失败的ID
  1421. $allUpdated = false;
  1422. $failedUniqids[] = $uniqid;
  1423. }
  1424. }
  1425. // 如果所有更新都成功,返回成功信息
  1426. if ($allUpdated) {
  1427. $list = \db('工单_bom资料')
  1428. ->whereIn('UNIQID', $uniqids) // 查询所有传入的UNIQID
  1429. ->select();
  1430. if (!empty($list)) {
  1431. $this->success('删除成功');
  1432. } else {
  1433. $this->GdGtpAiOrder($param['order']);
  1434. return $this->success('没有找到相关数据', []);
  1435. }
  1436. } else {
  1437. // 如果有更新失败的记录,返回失败的UNIQID
  1438. $this->error('部分更新失败,无法更新以下UNIQID: ' . implode(', ', $failedUniqids));
  1439. }
  1440. }
  1441. /**
  1442. * 前端选择订单时如果BOM资料数据为空则单独调用,重新生成最新
  1443. */
  1444. public function GdGtpAiOrder($order){
  1445. // 判断是否有指定的订单号
  1446. if (!empty($order)) {
  1447. // 查询单个订单的最大编号
  1448. $maxOrder = \db('工单_基本资料')
  1449. ->where('订单编号', 'like', "{$order}%")
  1450. ->order('订单编号', 'desc')
  1451. ->limit(1)
  1452. ->value('订单编号');
  1453. // 查询该订单的基本资料
  1454. $list = \db('工单_基本资料')
  1455. ->where('订单编号', 'like', "{$order}%")
  1456. ->order('订单编号', 'desc')
  1457. ->limit(1)
  1458. ->find();
  1459. // 如果面料数据为空,提示错误
  1460. if (empty($list['面料'])) {
  1461. $this->error('面料数据为空无法定义BOM');
  1462. }
  1463. // 处理订单编号
  1464. $numericPart = substr($maxOrder, 2);
  1465. $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
  1466. $param['订单编号'] = $order . $newNumericPart;
  1467. // 处理物料信息
  1468. $massage = empty($list['粘衬']) || $list['粘衬'] == '无' ? $list['面料'] : $list['面料'] . ',粘衬:' . $list['粘衬'];
  1469. $mianliao = $this->Gpt($massage);
  1470. // 插入物料数据
  1471. $data = [];
  1472. foreach ($mianliao as $key => $value) {
  1473. if (!empty($value) && $value !== '粘衬') { // 排除空值和粘衬
  1474. $data[] = [
  1475. 'BOM_工单编号' => $list['订单编号'],
  1476. 'BOM_物料名称' => $value,
  1477. 'Sys_rq' => date('Y-m-d H:i:s'),
  1478. 'Sys_ID' => '超级管理员'
  1479. ];
  1480. }
  1481. }
  1482. // 批量插入BOM资料
  1483. if (!empty($data)) {
  1484. \db('工单_bom资料')->insertAll($data);
  1485. }
  1486. $this->success('成功',$order);
  1487. } else {
  1488. // 如果没有指定订单号,批量查询订单号并处理
  1489. $has_bom = \db('工单_bom资料')->alias('a')->field('a.BOM_工单编号')->group('a.BOM_工单编号')->select();
  1490. $all_orders = \db('工单_基本资料')->alias('a')->field('a.订单编号')->where('a.面料', '<>', '')->group('a.订单编号')->select();
  1491. // 提取有BOM资料的订单号
  1492. $has_bom_orders = array_column($has_bom, 'BOM_工单编号');
  1493. // 筛选出没有对应BOM资料的订单号
  1494. $no_bom_orders = array_filter($all_orders, function ($order) use ($has_bom_orders) {
  1495. return !in_array($order['订单编号'], $has_bom_orders);
  1496. });
  1497. // 遍历没有BOM资料的订单
  1498. foreach ($no_bom_orders as $orderData) {
  1499. // 获取该订单号的最大订单编号
  1500. $maxOrder = \db('工单_基本资料')
  1501. ->where('订单编号', 'like', "{$orderData['订单编号']}%")
  1502. ->order('订单编号', 'desc')
  1503. ->limit(1)
  1504. ->value('订单编号');
  1505. // 获取该订单号的具体数据
  1506. $list = \db('工单_基本资料')
  1507. ->where('订单编号', 'like', "{$orderData['订单编号']}%")
  1508. ->order('订单编号', 'desc')
  1509. ->limit(1)
  1510. ->find();
  1511. if (empty($list['面料'])) {
  1512. $this->error("订单 {$orderData['订单编号']} 面料数据为空,无法定义BOM");
  1513. }
  1514. // 处理订单编号
  1515. $numericPart = substr($maxOrder, 2);
  1516. $newNumericPart = str_pad((int)$numericPart + 1, strlen($numericPart), '0', STR_PAD_LEFT);
  1517. $param['订单编号'] = $order . $newNumericPart;
  1518. // 处理物料信息
  1519. $massage = empty($list['粘衬']) || $list['粘衬'] == '无' ? $list['面料'] : $list['面料'] . ',粘衬:' . $list['粘衬'];
  1520. $mianliao = $this->Gpt($massage);
  1521. // 插入物料数据
  1522. $data = [];
  1523. foreach ($mianliao as $key => $value) {
  1524. if (!empty($value) && $value !== '粘衬') { // 排除空值和粘衬
  1525. $data[] = [
  1526. 'BOM_工单编号' => $list['订单编号'],
  1527. 'BOM_物料名称' => $value,
  1528. 'Sys_rq' => date('Y-m-d H:i:s'),
  1529. 'Sys_ID' => '超级管理员'
  1530. ];
  1531. }
  1532. }
  1533. // 批量插入BOM资料
  1534. if (!empty($data)) {
  1535. \db('工单_bom资料')->insertAll($data);
  1536. }
  1537. }
  1538. $this->success('成功');
  1539. }
  1540. }
  1541. /**
  1542. * 订单面料修改接口
  1543. * @return void
  1544. * @throws \think\Exception
  1545. * @throws \think\db\exception\BindParamException
  1546. * @throws \think\exception\PDOException
  1547. */
  1548. public function FabricEdit()
  1549. {
  1550. if ($this->request->isPost() === false){
  1551. $this->error('请求错误');
  1552. }
  1553. $param = Request::instance()->post();
  1554. if (empty($param)){
  1555. $this->error('请求错误');
  1556. }
  1557. // 判断前端传来的参数是否为空,避免空订单编号造成问题
  1558. if(empty($param[0]['BOM_工单编号'])){
  1559. $this->error('请求错误,请重新打开此页面');
  1560. }
  1561. foreach ($param as $key=>$value){
  1562. $data = $value;
  1563. unset($data['UNIQID']);
  1564. if ($value['UNIQID'] !== '' || !empty($value['UNIQID'])){
  1565. $sql = \db('工单_bom资料')
  1566. ->where('UNIQID',$value['UNIQID'])
  1567. ->fetchSql(true)
  1568. ->update($data);
  1569. $res = \db()->query($sql);
  1570. }else{
  1571. $sql = \db('工单_bom资料')
  1572. ->fetchSql(true)
  1573. ->insert($value);
  1574. $res = \db()->query($sql);
  1575. }
  1576. if ($res === false){
  1577. $this->error('修改失败');
  1578. }
  1579. }
  1580. $this->success('修改成功');
  1581. }
  1582. /**
  1583. * 订单BOM出库、退还详情显示
  1584. * @return void
  1585. * @throws \think\db\exception\DataNotFoundException
  1586. * @throws \think\db\exception\ModelNotFoundException
  1587. * @throws \think\exception\DbException
  1588. */
  1589. public function FabricDetail()
  1590. {
  1591. if ($this->request->isGet() === false){
  1592. $this->error('请求错误');
  1593. }
  1594. $param = $this->request->param();
  1595. if (empty($param) || !isset($param['order'])){
  1596. $this->error('参数错误');
  1597. }
  1598. if (isset($param['searchh']) || !empty($param['search'])){
  1599. $list['入库记录'] = \db('设备_报工日志')
  1600. ->where('order_id|款号',$param['order'])
  1601. ->where('name','入库')
  1602. ->field('id,order_id as 订单编号,款号,sum(number) as 数量,rq as 入库时间,sys_id as 入库人员,recipient as 入仓人员,receipt_number as 单号')
  1603. ->group('receipt_number')
  1604. ->order('入库时间 desc')
  1605. ->whereNull('Mod_rq')
  1606. ->select();
  1607. }else{
  1608. //出库记录查询
  1609. $list['出库记录'] = \db('设备_报工日志')
  1610. ->where('order_id|款号',$param['order'])
  1611. ->where('name','出库')
  1612. ->field('id,order_id as 订单编号,款号,sum(number) as 数量,rq as 出库时间,sys_id as 出库人员,receipt_number as 出库单据编号,recipient as 出库人员,receipt_number as 单号')
  1613. ->group('receipt_number')
  1614. ->order('出库时间 desc')
  1615. ->whereNull('Mod_rq')
  1616. ->select();
  1617. //退还记录查询
  1618. $list['退还记录'] = \db('设备_报工日志')
  1619. ->where('order_id|款号',$param['order'])
  1620. ->where('name','退还')
  1621. ->field('id,order_id as 订单编号,款号,sum(number) as 数量,rq as 退还时间,sys_id as 退还机台,recipient as 退还人员,receipt_number as 单号')
  1622. ->group('receipt_number')
  1623. ->order('退还时间 desc')
  1624. ->whereNull('Mod_rq')
  1625. ->select();
  1626. }
  1627. $this->success('成功',$list);
  1628. }
  1629. /**
  1630. * 入库、出库、退还详情数据
  1631. */
  1632. public function FabricDetaillist()
  1633. {
  1634. if ($this->request->isGet() === false){
  1635. $this->error('请求错误');
  1636. }
  1637. $param = $this->request->param();
  1638. if (empty($param) || !isset($param['order'])){
  1639. $this->error('参数错误');
  1640. }
  1641. // 定义查询字段
  1642. $fields = '
  1643. a.id,
  1644. a.order_id as 订单编号,
  1645. a.客户编号,
  1646. a.款号 as 生产款号,
  1647. a.款式,
  1648. a.物料名称,
  1649. b.BOM_计划用量 as 计划用料,
  1650. b.BOM_标准用量 as 定额用料,
  1651. b.BOM_计划门幅 as 计划门幅,
  1652. b.BOM_定额门幅 as 定额门幅,
  1653. b.BOM_实际用量 as 裁床实际用料,
  1654. b.Bom_领用数量 as 裁床领用面料,
  1655. b.BOM_退还数量 as 裁床退还数量,
  1656. b.BOM_库存总量 as 库存总量,
  1657. b.BOM_面料结余 as 面料结余,
  1658. a.number as 入库数量,
  1659. a.number as 出库数量,
  1660. b.BOM_投料单位 as 投料单位,
  1661. a.rq as 入库时间,
  1662. a.rq as 出库时间,
  1663. a.sys_id as 入库人员,
  1664. a.sys_id as 出库人员,
  1665. a.recipient as 领用人员,
  1666. a.receipt_number as 单号,
  1667. b.BOM_desc as 备注
  1668. ';
  1669. if (isset($param['searchh']) || !empty($param['search'])){
  1670. $list['入库记录'] = \db('设备_报工日志')->alias('a')
  1671. ->join('工单_bom资料 b', 'b.BOM_工单编号 = a.order_id AND a.物料名称 = b.BOM_物料名称', 'left') // 多条件关联
  1672. ->where('a.receipt_number', $param['order'])
  1673. ->where('a.name', '入库')
  1674. ->field($fields)
  1675. ->order('a.rq desc')
  1676. ->whereNull('a.Mod_rq')
  1677. ->select();
  1678. }else{
  1679. //出库记录查询
  1680. $list['出库记录'] = \db('设备_报工日志')->alias('a')
  1681. ->join('工单_bom资料 b', 'b.BOM_工单编号 = a.order_id AND a.物料名称 = b.BOM_物料名称', 'left') // 多条件关联
  1682. ->where('a.receipt_number', $param['order'])
  1683. ->where('a.name', '出库')
  1684. ->field($fields)
  1685. ->order('a.rq desc')
  1686. ->whereNull('a.Mod_rq')
  1687. ->select();
  1688. //退还记录查询
  1689. $list['退还记录'] = \db('设备_报工日志')->alias('a')
  1690. ->join('工单_bom资料 b', 'b.BOM_工单编号 = a.order_id AND a.物料名称 = b.BOM_物料名称', 'left') // 多条件关联
  1691. ->where('a.receipt_number', $param['order'])
  1692. ->where('a.name', '退还')
  1693. ->field($fields)
  1694. ->order('a.rq desc')
  1695. ->whereNull('a.Mod_rq')
  1696. ->select();
  1697. }
  1698. $this->success('成功',$list);
  1699. }
  1700. /**
  1701. * 入库、出库、退还删除
  1702. */
  1703. public function FabricDetaildel()
  1704. {
  1705. if ($this->request->isPost() === false){
  1706. $this->error('请求错误');
  1707. }
  1708. $param = Request::instance()->post();
  1709. if (empty($param)){
  1710. $this->error('请求错误');
  1711. }
  1712. // 判断UNIQID是否是逗号分隔的多个ID,如果是则拆分成数组,否则直接处理为单个ID
  1713. $ids = strpos($param['id'], ',') !== false ? explode(',', $param['id']) : [$param['id']];
  1714. $where = [];
  1715. $where['Mod_id'] = $param['Mod_id'];
  1716. $where['Mod_rq'] = date('Y-m-d H:i:s', time());
  1717. // 定义一个标志变量来追踪是否所有更新都成功
  1718. $allUpdated = true;
  1719. $failedUniqids = [];
  1720. // 遍历所有UNIQID并更新数据库
  1721. foreach ($ids as $id) {
  1722. // 更新指定UNIQID的记录
  1723. $result = \db('设备_报工日志')
  1724. ->where('id', $id)
  1725. ->update($where);
  1726. // 检查更新结果
  1727. if (!$result) {
  1728. // 如果某个UNIQID更新失败,记录失败的ID
  1729. $allUpdated = false;
  1730. $failedUniqids[] = $id;
  1731. }
  1732. }
  1733. // 如果所有更新都成功,返回成功信息
  1734. if ($allUpdated) {
  1735. $list = \db('设备_报工日志')
  1736. ->whereIn('id', $id) // 查询所有传入的UNIQID
  1737. ->select();
  1738. if (!empty($list)) {
  1739. $this->success('删除成功');
  1740. } else {
  1741. $this->GdGtpAiOrder($param['order']);
  1742. return $this->success('没有找到相关数据', []);
  1743. }
  1744. } else {
  1745. // 如果有更新失败的记录,返回失败的UNIQID
  1746. $this->error('部分更新失败,无法更新以下UNIQID: ' . implode(', ', $failedUniqids));
  1747. }
  1748. }
  1749. //GPT
  1750. public function Gpt($massage)
  1751. {
  1752. // 设置 API 密钥
  1753. $apiKey = 'sk-e0JuPjMntkbgi1BoMjrqyyzMKzAxILkQzyGMSy3xiMupuoWY'; // 替换为您的 API 密钥
  1754. // 要发送给 GPT 的消息
  1755. $messages = [
  1756. [
  1757. 'role' => 'user',
  1758. 'content' => '你好,帮我按照:面料1、面料2、面料3……来整理归纳下面的面料信息,我只需要面料信息,不需要其他:'.$massage
  1759. ]
  1760. ];
  1761. // 创建请求数据
  1762. $data = [
  1763. 'model' => 'gpt-3.5-turbo', // 使用的模型
  1764. 'messages' => $messages,
  1765. 'max_tokens' => 100, // 设置最大 token 数
  1766. ];
  1767. // 初始化 cURL
  1768. $ch = curl_init('https://niubi.zeabur.app/v1/chat/completions');
  1769. // 设置 cURL 选项
  1770. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  1771. curl_setopt($ch, CURLOPT_HTTPHEADER, [
  1772. 'Content-Type: application/json',
  1773. 'Authorization: Bearer ' . $apiKey,
  1774. ]);
  1775. curl_setopt($ch, CURLOPT_POST, true);
  1776. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  1777. curl_setopt($ch, CURLOPT_CAINFO, ROOT_PATH . '/public/uploads/cacert.pem');
  1778. // 执行请求
  1779. $response = curl_exec($ch);
  1780. // 检查错误
  1781. if (curl_errno($ch)) {
  1782. echo 'Error:' . curl_error($ch);
  1783. }
  1784. // 关闭 cURL
  1785. curl_close($ch);
  1786. // 解析和输出响应
  1787. $responseData = json_decode($response, true);
  1788. // 获取 GPT 的回复
  1789. if (isset($responseData['choices'][0]['message']['content'])) {
  1790. //获取返回内容
  1791. $gptReply = $responseData['choices'][0]['message']['content'];
  1792. // halt($gptReply);
  1793. //返回面料信息
  1794. $gptArray = explode('面料',$gptReply);
  1795. array_shift($gptArray);
  1796. foreach ($gptArray as $key=>$value){
  1797. $gptArray[$key] = preg_replace('/\s+/', '', substr($value,4));
  1798. }
  1799. return $gptArray;
  1800. } else {
  1801. echo "未能获取 GPT 的回复。";
  1802. }
  1803. }
  1804. /**
  1805. * 面料库存月份查询
  1806. */
  1807. public function fabricListmonth()
  1808. {
  1809. // 使用DATE_FORMAT函数提取年月部分,格式为 "YYYY-MM"
  1810. $list = \db('工单_bom资料')
  1811. ->alias('a')
  1812. ->join('工单_基本资料 b', 'b.订单编号 = a.BOM_工单编号')
  1813. ->field('DATE_FORMAT(a.Sys_rq, "%Y-%m") as date') // 提取年月,格式化为 "YYYY-MM"
  1814. ->group('date')
  1815. ->order('date desc')
  1816. ->select();
  1817. // 格式化返回的数据,生成期望的结构
  1818. $result = [];
  1819. foreach ($list as $item) {
  1820. $result[] = ['date' => $item['date']]; // 返回格式为 {"date": "YYYY-MM"}
  1821. }
  1822. if (!empty($result)) {
  1823. $this->success('成功', $result); // 返回查询到的结果
  1824. } else {
  1825. $this->success('没有找到相关数据', []); // 如果没有数据,返回空数组
  1826. }
  1827. }
  1828. /**
  1829. * 面料库存列表
  1830. * @return void
  1831. * @throws \think\db\exception\DataNotFoundException
  1832. * @throws \think\db\exception\ModelNotFoundException
  1833. * @throws \think\exception\DbException
  1834. */
  1835. public function fabricList()
  1836. {
  1837. if ($this->request->isGet() === false) {
  1838. $this->error('请求错误');
  1839. }
  1840. $param = $this->request->param();
  1841. $where = [];
  1842. // 根据传入的参数构造查询条件
  1843. if (isset($param['order'])) {
  1844. $where['a.BOM_工单编号|b.生产款号|a.BOM_物料名称'] = ['like', $param['order'] . '%'];
  1845. }
  1846. if (isset($param['mouth'])) {
  1847. $where['a.Sys_rq'] = ['like', $param['mouth'] . '%'];
  1848. }
  1849. // 分页参数,防止未传递时出错
  1850. $page = isset($param['page']) ? (int)$param['page'] : 1;
  1851. $limit = isset($param['limit']) ? (int)$param['limit'] : 50; // 默认每页50条数据
  1852. // 获取数据
  1853. $data = \db('工单_面料资料')
  1854. ->alias('a')
  1855. ->join('工单_基本资料 b', 'b.订单编号 = a.BOM_工单编号')
  1856. ->field('a.BOM_工单编号 as 订单编号,a.BOM_颜色 as 颜色, b.生产款号 as 生产款号, b.客户编号 as 客户编号, b.款式 as 款式,
  1857. a.BOM_物料编码,a.BOM_物料名称 as 物料名称, a.BOM_投料单位 as 投料单位,
  1858. a.BOM_实际用量 as 裁床实际用料, a.BOM_领用数量 as 裁床领用面料, a.BOM_退还数量 as 裁床退回仓库面料,
  1859. a.BOM_desc as 备注, a.UNIQID, a.BOM_库存总量 as 入库总量, a.BOM_计划门幅 as 计划门幅, a.BOM_定额门幅 as 定额门幅,
  1860. a.BOM_面料结余 as 面料结余, a.Sys_ID as ID, a.Sys_rq as 日期')
  1861. ->where($where)
  1862. ->group('a.BOM_物料编码')
  1863. ->order("a.BOM_工单编号 desc")
  1864. ->limit(($page - 1) * $limit, $limit)
  1865. ->select();
  1866. // 获取数据总数
  1867. $count = \db('工单_面料资料')
  1868. ->alias('a')
  1869. ->join('工单_基本资料 b', 'b.订单编号 = a.BOM_工单编号')
  1870. ->where($where)
  1871. ->count();
  1872. // 如果查询到数据
  1873. if (!empty($data)) {
  1874. // 构建返回数据
  1875. $list = [
  1876. 'total' => $count, // 总数
  1877. 'table' => $data // 数据内容
  1878. ];
  1879. // 返回成功响应
  1880. $this->success('成功', $list);
  1881. } else {
  1882. // 没有查询到数据
  1883. $this->success('没有找到相关数据', []);
  1884. }
  1885. }
  1886. /**
  1887. * 单条面料详情
  1888. * @return void
  1889. * @throws \think\db\exception\DataNotFoundException
  1890. * @throws \think\db\exception\ModelNotFoundException
  1891. * @throws \think\exception\DbException
  1892. */
  1893. public function oneFabricDetail()
  1894. {
  1895. if ($this->request->isGet() === false){
  1896. $this->error('请求错误');
  1897. }
  1898. $param = $this->request->param();
  1899. if (empty($param)){
  1900. $this->error('参数错误');
  1901. }
  1902. //面料入库记录
  1903. $list['入库'] = \db('设备_报工日志')
  1904. ->where('',$param['order'])
  1905. ->where('物料名称',$param['fabricName'])
  1906. ->where('name','入库')
  1907. ->where('Mod_rq',null)
  1908. ->field('order_id as 订单编号,款号,物料编码,物料名称,number as 数量,rq as 日期,sys_id as 操作机台,recipient as 入仓人员')
  1909. ->select();
  1910. //面料出库记录
  1911. $list['出库'] = \db('设备_报工日志')
  1912. ->where('order_id',$param['order'])
  1913. ->where('物料名称',$param['fabricName'])
  1914. ->where('name','出库')
  1915. ->where('Mod_rq',null)
  1916. ->field('order_id as 订单编号,款号,物料名称,number as 数量,rq as 日期,sys_id as 操作机台,receipt_number as 出库单据编号,recipient as 领用人员')
  1917. ->select();
  1918. //面料退还记录
  1919. $list['退还'] = \db('设备_报工日志')
  1920. ->where('order_id',$param['order'])
  1921. ->where('物料名称',$param['fabricName'])
  1922. ->where('name','退还')
  1923. ->where('Mod_rq',null)
  1924. ->field('order_id as 订单编号,款号,物料名称,number as 数量,rq as 日期,sys_id as 操作机台,recipient as 退还人员')
  1925. ->select();
  1926. $this->success('成功',$list);
  1927. }
  1928. /**
  1929. * 单据号查询数据
  1930. * @return void
  1931. * @throws \think\db\exception\DataNotFoundException
  1932. * @throws \think\db\exception\ModelNotFoundException
  1933. * @throws \think\exception\DbException
  1934. */
  1935. public function ReceiptDetail()
  1936. {
  1937. if ($this->request->isGet() === false){
  1938. $this->error('请求错误');
  1939. }
  1940. $param = $this->request->param();
  1941. if (empty($param)){
  1942. $this->error('单据编号参数错误');
  1943. }
  1944. $list = \db('设备_报工日志')
  1945. // ->where('receipt_number','like','%',$param['receipt'].'%')
  1946. ->where('receipt_number',$param['receipt'])
  1947. ->field('order_id as 订单编号,款号,物料名称,number as 数量,rq as 日期,sys_id as 操作机台,receipt_number as 出库单据编号,recipient as 领用人员')
  1948. ->whereNull('Mod_rq')
  1949. ->select();
  1950. if (empty($list)){
  1951. $this->error('未找到该出库单');
  1952. }else{
  1953. $this->success('成功',$list);
  1954. }
  1955. }
  1956. /**
  1957. * 出库单列表
  1958. * @return void
  1959. * @throws \think\db\exception\DataNotFoundException
  1960. * @throws \think\db\exception\ModelNotFoundException
  1961. * @throws \think\exception\DbException
  1962. */
  1963. public function ReceiptList()
  1964. {
  1965. if ($this->request->isGet() === false){
  1966. $this->error('请求错误');
  1967. }
  1968. $param = $this->request->param();
  1969. if (empty($param)){
  1970. $this->error('参数错误');
  1971. }
  1972. $where= [];
  1973. if (isset($param['search'])) {
  1974. $where['物料名称|款号|order_id|receipt_number'] = ['like', $param['search'] . '%'];
  1975. }
  1976. if (isset($param['mouth'])) {
  1977. $where['rq'] = ['like', $param['mouth'] . '%'];
  1978. }
  1979. $page = $param['page'];
  1980. $limit = $param['limit'];
  1981. $list = \db('设备_报工日志')
  1982. ->where($where)
  1983. ->field('receipt_number as 出库单,order_id as 订单编号,款号,物料名称,rq as 日期,sys_id as 操作机台,recipient as 领料人员,name as 单号类型')
  1984. ->group('出库单')
  1985. ->order('rq desc')
  1986. ->where('Mod_rq',null)
  1987. ->limit(($page-1)*$limit,$limit)
  1988. ->select();
  1989. $count = \db('设备_报工日志')
  1990. ->where($where)
  1991. ->field('receipt_number as 出库单')
  1992. ->group('出库单')
  1993. ->where('Mod_rq',null)
  1994. ->order('rq desc')
  1995. ->select();
  1996. if (empty($list)){
  1997. $this->success('未找到数据');
  1998. }else{
  1999. $data['total'] = count($count);
  2000. $data['table'] = $list;
  2001. $this->success('成功',$data);
  2002. }
  2003. }
  2004. /**
  2005. * 出库单左侧菜单
  2006. * @return void
  2007. * @throws \think\db\exception\DataNotFoundException
  2008. * @throws \think\db\exception\ModelNotFoundException
  2009. * @throws \think\exception\DbException
  2010. */
  2011. public function getReceiptTab()
  2012. {
  2013. if ($this->request->isGet() === false){
  2014. $this->error('请求错误');
  2015. }
  2016. $list = \db('设备_报工日志')
  2017. ->field([
  2018. "DATE_FORMAT(rq, '%Y-%m') AS month",
  2019. ])
  2020. ->group('month')
  2021. ->order('month DESC')
  2022. ->select();
  2023. if (empty($list)){
  2024. $this->error('未查询到入库、出库、退还数据');
  2025. }else{
  2026. $this->success('成功',$list);
  2027. }
  2028. }
  2029. /**
  2030. * 获取入库单号、出库单号
  2031. * @return void
  2032. */
  2033. public function gitReceiptNumber()
  2034. {
  2035. if ($this->request->isGet() === false){
  2036. $this->error('请求错误');
  2037. }
  2038. $param = $this->request->param();
  2039. if (empty($param)){
  2040. $this->error('参数错误');
  2041. }
  2042. $lastNumber = \db('设备_报工日志')
  2043. ->where('receipt_number','like',$param['number'].'%')
  2044. ->order('receipt_number desc')
  2045. ->limit(1)
  2046. ->column('receipt_number as 单号');
  2047. if (empty($lastNumber)){
  2048. $num = 1;
  2049. }else{
  2050. $num = (int)(substr($lastNumber[0],12,3))+1;
  2051. }
  2052. if ($num < 10){
  2053. $num = '00'.$num;
  2054. }elseif ($num>=10 && $num<100){
  2055. $num = '0'.$num;
  2056. }else{
  2057. $num;
  2058. }
  2059. $number = $param['number'].date('Ymd',time()).'-'.$num;
  2060. $lastNumber = \db('设备_报工日志')
  2061. ->where('name','出库')
  2062. ->order('recipient desc')
  2063. ->group('recipient')
  2064. ->limit(1)
  2065. ->value('recipient as 人员');
  2066. $data = [
  2067. 'number' => $number,
  2068. 'username' => $lastNumber
  2069. ];
  2070. $this->success('成功', $data);
  2071. }
  2072. }