WorkOrder.php 85 KB

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