Facility.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use think\Db;
  5. use think\Request;
  6. /**
  7. * 质量继绩效管理
  8. */
  9. class Facility extends Api{
  10. protected $noNeedLogin = ['*'];
  11. protected $noNeedRight = ['*'];
  12. /**
  13. *1.0查询订单号、款号(通用接口)
  14. * 查询对应订单编号或生产款号
  15. */
  16. public function Apiorder() {
  17. if ($this->request->isGet() === false) {
  18. $this->error('请求错误');
  19. }
  20. $param = $this->request->param();
  21. //是否有code字段传送过来【机台需要】
  22. if(!empty($param['code'])){
  23. //查询当前工序已报工过,近一个月工单数据
  24. $res = Db::name('设备_产量计酬')->alias('c')
  25. ->field('c.订单编号,j.生产款号,j.款式')
  26. ->join('工单_基本资料 j', 'c.订单编号 = j.订单编号', 'left')
  27. ->where('c.订单编号|j.生产款号|j.款式','like','%'.$param['search'].'%')
  28. ->group('c.订单编号')
  29. ->where('工序名称',$param['code'])
  30. ->select();
  31. $this->success('成功', [
  32. 'list' => $res,
  33. 'total' => count($res) // 返回数据条数
  34. ]);
  35. }else{
  36. //模糊查询所有订单数据【其他页面需要调用】
  37. $res = \db('工单_基本资料')
  38. ->field('订单编号,生产款号,款式')
  39. ->where('订单编号|生产款号|款式','like','%'.$param['search'].'%')
  40. ->where('Mod_rq', null)
  41. ->select();
  42. $this->success('成功', [
  43. 'list' => $res,
  44. 'total' => count($res) // 返回数据条数
  45. ]);
  46. }
  47. }
  48. /**
  49. * 1.1查询子订单编号
  50. * 通过订单编号查询对应子订单编号
  51. */
  52. public function Apiorderids() {
  53. if ($this->request->isGet() === false) {
  54. $this->error('请求错误');
  55. }
  56. $param = $this->request->param();
  57. $gdlist = \db('工单_印件资料')
  58. ->field('子订单编号,款号,颜色备注')
  59. ->where('订单编号',$param['order'])
  60. ->where('Mod_rq', null)
  61. ->select();
  62. $this->success('成功', [
  63. 'list' => $gdlist,
  64. ]);
  65. }
  66. /**
  67. * 1.2查询新增基本信息
  68. * 新增查询信息
  69. */
  70. public function queryOrderSize() {
  71. // 检查请求类型是否为GET
  72. if ($this->request->isGet() === false) {
  73. $this->error('请求错误');
  74. }
  75. $param = $this->request->param();
  76. //问题分类
  77. $fetchCategory = \db('db_问题分类')->field('问题类型, classification as 分类名称,num')->order('num desc')->select();
  78. $groupedCategories = [];
  79. // 遍历数据,将相同分类名称的问题类型归类
  80. foreach ($fetchCategory as $item) {
  81. $categoryname = $item['分类名称'];
  82. $category = $item['问题类型'];
  83. // 如果分类名称不存在,则初始化为空数组
  84. if (!isset($groupedCategories[$categoryname])) {
  85. $groupedCategories[$categoryname] = [];
  86. }
  87. // 避免重复添加相同的问题类型
  88. if (!in_array($category, $groupedCategories[$categoryname])) {
  89. $groupedCategories[$categoryname][] = $category;
  90. }
  91. }
  92. $gdlist = \db('工单_基本资料')
  93. ->field('订单编号,生产款号,款式,订单数量')
  94. ->where(['订单编号|生产款号' => $param['订单编号']])
  95. ->where('Mod_rq', null)
  96. ->find();
  97. if (empty($gdlist)) {
  98. $this->error('未找到相关数据');
  99. }
  100. // 查询订单尺码信息
  101. $sizeData = \db('工单_印件资料')->where(['订单编号' => $gdlist['订单编号']])->where('Mod_rq', null)->select();
  102. if (empty($sizeData)) {
  103. $this->error('未找到相关数据');
  104. }
  105. // 计算所有尺码数据
  106. $sizes = [];
  107. foreach ($sizeData as $order) {
  108. foreach ($order as $key => $value) {
  109. if (strpos($key, 'cm') === 0 && strpos($key, 'cmsl') === false && $value !== null && $value !== '') {
  110. $sizes[] = $value;
  111. }
  112. }
  113. }
  114. // 去重后所有子订单重复的尺码数据
  115. $sizes = array_values(array_unique($sizes));
  116. // 获取颜色备注并统计每个颜色的sctotal和zdtotal
  117. $colorData = []; // 用于存储每个颜色备注对应的sctotal和zdtotal
  118. foreach ($sizeData as $item) {
  119. if (!empty($item['颜色备注'])) {
  120. $color = $item['颜色备注'];
  121. $sctotal = (int)$item['sctotal'];
  122. $zdtotal = (int)$item['zdtotal'];
  123. if (isset($colorData[$color])) {
  124. $colorData[$color]['sctotal'] += $sctotal;
  125. $colorData[$color]['zdtotal'] += $zdtotal;
  126. } else {
  127. $colorData[$color] = [
  128. 'sctotal' => $sctotal,
  129. 'zdtotal' => $zdtotal
  130. ];
  131. }
  132. }
  133. }
  134. // 获取颜色备注(去重)
  135. $colorremark = array_values(array_unique(array_keys($colorData)));
  136. //面料分类|面料名称
  137. $getarr = \db('工单_bom资料')
  138. ->field('物料分类,BOM_物料名称')
  139. ->where('BOM_工单编号', $param['订单编号'])
  140. ->where('Mod_rq', null)
  141. ->select();
  142. $fabricArr = []; // 存储拼接后的数据
  143. foreach ($getarr as $value) {
  144. $materialName = $value['BOM_物料名称'];
  145. // 如果物料分类为空,就用'-'代替
  146. $bomDesc = !empty($value['物料分类']) ? $value['物料分类'] : '';
  147. // 拼接字符串,并去除多余空格
  148. $combinedData = trim($bomDesc . ' - ' . $materialName);
  149. // 存入数组
  150. $fabricArr[] = $combinedData;
  151. // $bomDesc = !empty($value['物料分类']) ? $value['物料分类'] : ''; // 防止null
  152. // // 拼接字符串,并去除可能的前后空格
  153. // $combinedData = trim($bomDesc . ' - ' . $materialName, ' -');
  154. // // 存入数组
  155. // $fabricArr[] = $combinedData;
  156. }
  157. // 获取面料颜色
  158. $getAllFabricData = \db('工单_面料资料')
  159. ->field('BOM_物料名称,BOM_定额门幅,BOM_计划门幅,BOM_颜色')
  160. ->where('BOM_工单编号', $param['订单编号'])
  161. ->where('Mod_rq', null)
  162. ->select();
  163. // 用于统计每个物料的用料情况
  164. $uniqueFabricData = []; // 去重后的面料数据
  165. foreach ($getAllFabricData as $fabric) {
  166. $key = $fabric['BOM_颜色'] . '-' . $fabric['BOM_物料名称']; // 以颜色和物料名称为唯一标识
  167. $uniqueFabricData[$key] = $fabric; // 使用唯一标识作为数组的键,自动去重
  168. }
  169. // 重建数组索引,移除键名
  170. $uniqueFabricData = array_values($uniqueFabricData);
  171. $materialUsage = [];
  172. // 遍历每种颜色的统计数据
  173. foreach ($colorData as $color => $data) {
  174. // 遍历去重后的面料数据
  175. foreach ($uniqueFabricData as $fabric) {
  176. // 判断颜色是否匹配
  177. if ($fabric['BOM_颜色'] === $color) {
  178. // 直接统计每个物料的数量,而不进行用料的计算
  179. $materialUsage[$color][$fabric['BOM_物料名称']][] = $fabric; // 使用物料名称作为键,存储所有相关的面料数据
  180. }
  181. }
  182. }
  183. // 生成实际用料数据
  184. $actualUsage = [];
  185. foreach ($materialUsage as $color => $materials) {
  186. foreach ($materials as $materialName => $fabricData) {
  187. // 获取该颜色下的 sctotal 和 zdtotal
  188. $sctotal = isset($colorData[$color]['sctotal']) ? $colorData[$color]['sctotal'] : 0;
  189. $zdtotal = isset($colorData[$color]['zdtotal']) ? $colorData[$color]['zdtotal'] : 0;
  190. // 获取定额门幅和计划门幅
  191. $standardWidth = isset($fabricData[0]['BOM_定额门幅']) ? $fabricData[0]['BOM_定额门幅'] : 0;
  192. $plannedWidth = isset($fabricData[0]['BOM_计划门幅']) ? $fabricData[0]['BOM_计划门幅'] : 0;
  193. // 直接根据去重后的面料数据进行统计
  194. $actualUsage[] = [
  195. '颜色' => $color,
  196. '物料名称' => $materialName,
  197. '定额门幅' => $standardWidth,
  198. '计划门幅' => $plannedWidth,
  199. 'sctotal' => $sctotal,
  200. 'zdtotal' => $zdtotal
  201. ];
  202. }
  203. }
  204. foreach ($actualUsage as &$item) {
  205. // 如果 'sctotal' 或 '定额门幅' 为空,则默认为 0
  206. $sctotal = isset($item['sctotal']) && is_numeric($item['sctotal']) ? $item['sctotal'] : 0;
  207. $demf = isset($item['定额门幅']) && is_numeric($item['定额门幅']) ? $item['定额门幅'] : 0;
  208. $zdtotal = isset($item['zdtotal']) && is_numeric($item['zdtotal']) ? $item['zdtotal'] : 0;
  209. $jhmf = isset($item['计划门幅']) && is_numeric($item['计划门幅']) ? $item['计划门幅'] : 0;
  210. $item['实际用料'] = $sctotal * $demf;
  211. $item['计划用料'] = $zdtotal * $jhmf;
  212. }
  213. // 选择显示的字段
  214. $fieldsToShow = ['颜色', '物料名称', '实际用料', '计划用料'];
  215. $finalResult = array();
  216. foreach ($actualUsage as $item) {
  217. $filteredItem = array();
  218. foreach ($fieldsToShow as $field) {
  219. if (isset($item[$field])) {
  220. $filteredItem[$field] = $item[$field];
  221. }
  222. }
  223. $finalResult[] = $filteredItem;
  224. }
  225. //定义接口
  226. $this->success('成功', [
  227. 'list' => $gdlist,
  228. 'colorremark' => $colorremark,
  229. 'fetchCategory' => $groupedCategories,
  230. 'FabricData' => $fabricArr,
  231. 'size' => $sizes,
  232. '面料统计' => $finalResult
  233. ]);
  234. }
  235. /**
  236. * 1.3新增次品或返工
  237. * 新增到设备_质量汇总表
  238. */
  239. public function ApiAddDefective(){
  240. if (!$this->request->isPost()) {
  241. $this->error('非法请求');
  242. }
  243. $params = $this->request->param();
  244. if (empty($params)){
  245. $this->error('参数错误');
  246. }
  247. $res = \db('设备_质量汇总')->where('mod_rq', null)->order('status_num desc')->find();
  248. //记录每次新增次数排序,判断是否有返回值,没有则从1开始
  249. $status_num = isset($res['status_num']) ? $res['status_num'] : 1;
  250. // 构建单条记录的函数,传递 $list_gd 作为参数
  251. function buildRecords($item,$status_num) {
  252. // 拆分物料名称(假设格式为 面料分类-面料名称)
  253. $materialParts = explode('-', $item['物料名称']);
  254. // 面料分类
  255. $materialCategory = isset($materialParts[0]) ? $materialParts[0] : '';
  256. // 面料名称
  257. $materialName = isset($materialParts[1]) ? $materialParts[1] : '';
  258. // 获取最新的单据编号
  259. $resd = \db('设备_质量汇总')
  260. ->field('单据编号')
  261. ->where('mod_rq', null)
  262. ->order('单据编号 desc')
  263. ->find();
  264. // 获取当前日期
  265. $currentDate = date('Ymd');
  266. // 如果查询到最新的单据编号
  267. if ($resd) {
  268. // 提取最新单据编号的日期和流水号部分
  269. preg_match('/ZL(\d{8})(\d{4})/', $resd['单据编号'], $matches);
  270. // 如果匹配成功,进行累加
  271. if ($matches) {
  272. $lastDate = $matches[1];
  273. $lastNumber = (int)$matches[2]; // 将流水号转为数字
  274. // 如果当前日期和最新单据的日期不同,则从0001开始
  275. $newNumber = ($currentDate !== $lastDate) ? '0001' : str_pad($lastNumber + 1, 4, '0', STR_PAD_LEFT);
  276. } else {
  277. // 如果没有匹配到正确的格式,则从0001开始
  278. $newNumber = '0001';
  279. }
  280. } else {
  281. // 如果没有查询到单据编号,默认从0001开始
  282. $newNumber = '0001';
  283. }
  284. return [
  285. '单据编号' => 'ZL' . $currentDate . $newNumber,
  286. '订单编号' => $item['订单编号'],
  287. '生产款号' => $item['生产款号'],
  288. '款式' => $item['款式'],
  289. '颜色' => $item['颜色'],
  290. '尺码' => $item['尺码'],
  291. '数量' => $item['数量'],
  292. '组别' => $item['组别'],
  293. '实际用料' => $item['实际用料'],
  294. '计划用料' => $item['计划用料'],
  295. '备注' => $item['备注'],
  296. '问题分类' => $item['问题分类'],
  297. 'sczl_rq' => date('Y-m-d H:i:s'),
  298. 'Sys_rq' => $item['Sys_rq'],
  299. 'Sys_id' => $item['Sys_id'],
  300. '状态' => $item['状态'],
  301. 'status_num' => $status_num + 1,
  302. '面料分类' => $materialCategory,
  303. '面料名称' => $materialName,
  304. ];
  305. }
  306. // 检查是否是索引数组(多条记录)
  307. if (isset($params[0]) && is_array($params[0])) {
  308. foreach ($params as $item) {
  309. $list[] = buildRecords($item,$status_num);
  310. }
  311. } else {
  312. // 处理单条记录
  313. $list[] = buildRecords($params,$status_num);
  314. }
  315. // 插入前统计问题分类的使用次数
  316. foreach ($list as $item) {
  317. $category = $item['问题分类'];
  318. // 查询满足 问题类型 + classification 的记录
  319. $record = \db('db_问题分类')
  320. ->where('问题类型', $category)
  321. // 可选,防止 null 报错
  322. ->whereNotNull('classification')
  323. ->find();
  324. if ($record) {
  325. $newNum = intval($record['num']) + 1;
  326. // 使用 update 替代 setInc,手动加1
  327. $updateSql = \db('db_问题分类')->fetchSql(true)
  328. ->where('id', $record['id']) // 建议用主键精确定位
  329. ->update(['num' => $newNum]);
  330. \db()->query($updateSql);
  331. }
  332. }
  333. $result = \db('设备_质量汇总')->insertAll($list);
  334. if ($result) {
  335. $this->success('数据插入成功 : ' . date('H:i:s'));
  336. } else {
  337. $this->error('数据插入失败');
  338. }
  339. }
  340. /**
  341. * 1.4质量管理左侧菜单栏查询
  342. */
  343. public function ApiMouthlist() {
  344. // 检查请求类型是否为GET
  345. if ($this->request->isGet() === false) {
  346. $this->error('请求错误');
  347. }
  348. $param = $this->request->param();
  349. // 查询符合条件的数据
  350. $list = \db('设备_质量汇总')
  351. ->where('状态', $param['code'])
  352. ->where('mod_rq', null)
  353. ->order('Sys_rq desc')
  354. ->group('Sys_rq')
  355. ->select();
  356. if (empty($list)) {
  357. $this->success('成功', '');
  358. return;
  359. //$this->error('未查询到数据');
  360. }
  361. // 用于存储按年和月分类的数据
  362. $data = [];
  363. // 遍历查询结果,将日期按年、月分组
  364. foreach ($list as $item) {
  365. // 获取 Sys_rq 字段的值(日期)
  366. $sys_rq = $item['Sys_rq'];
  367. // 提取年、月、日
  368. $year = date('Y', strtotime($sys_rq));
  369. $month = date('Y-m', strtotime($sys_rq));
  370. $day = date('Y-m-d', strtotime($sys_rq));
  371. // 将数据按年、月、日分类
  372. if (!isset($data[$year])) {
  373. $data[$year] = [];
  374. }
  375. if (!isset($data[$year][$month])) {
  376. $data[$year][$month] = [];
  377. }
  378. // 将日期加入到对应的年、月下
  379. $data[$year][$month][] = $day;
  380. }
  381. $this->success('成功', $data);
  382. }
  383. /**
  384. * 1.5查询单据汇总次片、返工列表数据
  385. */
  386. public function ApiSubPieceAnd() {
  387. if ($this->request->isGet() === false) {
  388. $this->error('请求错误');
  389. }
  390. $params = $this->request->param();
  391. $where = ['mod_rq' => null];
  392. if (!empty($params['code'])) {
  393. $where['状态'] = $params['code'];
  394. }
  395. if (!empty($params['组别'])) {
  396. $where['组别'] = $params['组别'];
  397. }
  398. if (!empty($params['search'])) {
  399. $where['单据编号|订单编号|生产款号|面料名称|面料分类|颜色|问题分类|款式|组别'] = ['like', '%' . $params['search'] . '%'];
  400. }
  401. // 处理日期查询(支持按天和按月)
  402. if (!empty($params['Sys_rq'])) {
  403. if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $params['Sys_rq'])) {
  404. // 按天查询
  405. $where['Sys_rq'] = $params['Sys_rq'];
  406. } elseif (preg_match('/^\d{4}-\d{2}$/', $params['Sys_rq'])) {
  407. // 按月查询
  408. $where['Sys_rq'] = ['like', $params['Sys_rq'] . '%'];
  409. }elseif (preg_match('/^\d{4}$/', $params['Sys_rq'])) {
  410. // 按年查询
  411. //需要年份查询将代码屏蔽取消
  412. // $where['Sys_rq'] = $params['Sys_rq'];
  413. $this->success('成功', ['data' => '', 'total' => '']);
  414. }
  415. }
  416. $data = \db('设备_质量汇总')
  417. ->field('单据编号,订单编号,生产款号,面料名称,面料分类,问题分类,颜色,数量,款式,Sys_rq,尺码,组别')
  418. ->where($where)
  419. ->select();
  420. $mergedData = [];
  421. foreach ($data as $item) {
  422. //一条数据
  423. if (!isset($mergedData[$item['单据编号']])) {
  424. $mergedData[$item['单据编号']] = [
  425. '单据编号' => $item['单据编号'],
  426. '订单编号' => $item['订单编号'],
  427. '款式' => $item['款式'],
  428. '生产款号' => $item['生产款号'],
  429. '问题分类' => $item['问题分类'],
  430. '颜色' => $item['颜色'],
  431. '面料名称' => $item['面料名称'],
  432. '面料分类' => $item['面料分类'],
  433. '数量' => $item['数量'],
  434. '组别' => $item['组别'],
  435. '尺码' => $item['尺码'],
  436. 'Sys_rq' => $item['Sys_rq']
  437. ];
  438. } else {
  439. // 多条合并数据、数量进行累加
  440. $mergedData[$item['单据编号']]['问题分类'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['问题分类']), [$item['问题分类']]))));
  441. $mergedData[$item['单据编号']]['颜色'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['颜色']), [$item['颜色']]))));
  442. $mergedData[$item['单据编号']]['面料名称'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['面料名称']), [$item['面料名称']]))));
  443. $mergedData[$item['单据编号']]['面料分类'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['面料分类']), [$item['面料分类']]))));
  444. $mergedData[$item['单据编号']]['订单编号'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['订单编号']), [$item['订单编号']]))));
  445. $mergedData[$item['单据编号']]['生产款号'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['生产款号']), [$item['生产款号']]))));
  446. $mergedData[$item['单据编号']]['款式'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['款式']), [$item['款式']]))));
  447. $mergedData[$item['单据编号']]['尺码'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['尺码']), [$item['尺码']]))));
  448. $mergedData[$item['单据编号']]['组别'] = implode(',', array_unique(array_filter(array_merge(explode(',', $mergedData[$item['单据编号']]['组别']), [$item['组别']]))));
  449. $mergedData[$item['单据编号']]['数量'] += $item['数量'];
  450. }
  451. }
  452. $finalData = array_values($mergedData);
  453. $this->success('成功', ['data' => $finalData, 'total' => count($finalData)]);
  454. }
  455. /**
  456. * 1.6查询单据明细次片、返工列表数据
  457. */
  458. public function ApiSubPieceAndReworkList() {
  459. if ($this->request->isGet() === false) {
  460. $this->error('请求错误');
  461. }
  462. $params = $this->request->param();
  463. $where = ['mod_rq' => null];
  464. // 状态查询
  465. if (!empty($params['code'])) {
  466. $where['状态'] = $params['code'];
  467. }
  468. // 关键词模糊搜索
  469. if (!empty($params['search'])) {
  470. $where['单据编号|订单编号|生产款号|面料名称|面料分类|颜色|问题分类'] = ['like', '%' . $params['search'] . '%'];
  471. }
  472. // 处理日期查询(支持按天和按月)
  473. if (!empty($params['Sys_rq'])) {
  474. if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $params['Sys_rq'])) {
  475. // 按天查询(2025-03-27)
  476. $where['Sys_rq'] = $params['Sys_rq'];
  477. } elseif (preg_match('/^\d{4}-\d{2}$/', $params['Sys_rq'])) {
  478. // 按月查询(2025-03),匹配该月的所有数据
  479. $where['Sys_rq'] = ['like', $params['Sys_rq'] . '%'];
  480. }
  481. }
  482. $res = \db('设备_质量汇总')
  483. ->where($where)
  484. ->limit(($params['page'] - 1) * $params['limit'], $params['limit'])
  485. ->order('id','desc')
  486. ->select();
  487. $this->success('获取成功', ['data' => $res, 'total' => count($res)]);
  488. }
  489. /**
  490. * 查询获取问题分类
  491. */
  492. public function getProblemCategories() {
  493. if (!$this->request->isGet()) {
  494. $this->error('请求错误');
  495. }
  496. $params = $this->request->param();
  497. // 仅查询未被删除的数据
  498. $where = ['mod_rq' => null];
  499. // 允许通过问题类型进行搜索
  500. if (!empty($params['search'])) {
  501. $where['问题类型'] = ['like', '%' . $params['search'] . '%'];
  502. }
  503. $data = \db('db_问题分类')->where($where)->order('update_time desc')->select();
  504. if (!$data) {
  505. $this->error('未查询到数据');
  506. }
  507. $this->success('获取成功', ['data' => $data, 'total' => count($data)]);
  508. }
  509. /**
  510. * 添加问题分类接口
  511. */
  512. public function addProblemCategory() {
  513. if (!$this->request->isPost()) {
  514. $this->error('非法请求');
  515. }
  516. $params = $this->request->param();
  517. if (empty($params['问题类型'])) {
  518. $this->error('问题类型不能为空');
  519. }
  520. $insertData = [
  521. '问题类型' => $params['问题类型'],
  522. 'sys_id' => $params['sys_id'],
  523. 'classification' => $params['classification'],
  524. 'Sys_rq' => date('Y-m-d H:i:s')
  525. ];
  526. $sql = \db('db_问题分类')
  527. ->fetchSql(true)
  528. ->insert($insertData);
  529. $res = \db()->query($sql);
  530. $this->success('添加成功');
  531. }
  532. /**
  533. * 删除问题分类接口
  534. */
  535. public function deleteProblemCategory() {
  536. if (!$this->request->isPost()) {
  537. $this->error('非法请求');
  538. }
  539. $params = $this->request->param();
  540. if (empty($params['id'])) {
  541. $this->error('ID 不能为空');
  542. }
  543. $updateData = [
  544. 'mod_rq' => date('Y-m-d H:i:s')
  545. ];
  546. $res = \db('db_问题分类')->where('id', $params['id'])->update($updateData);
  547. if ($res) {
  548. $this->success('删除成功');
  549. } else {
  550. $this->error('删除失败');
  551. }
  552. }
  553. /**
  554. * 机台设备查询
  555. */
  556. public function getMachineDeviceTypes(){
  557. $res = \db('设备_基本资料')
  558. ->where('mod_rq', null)
  559. ->where('设备名称','=','1')
  560. ->select();
  561. $this->success('成功', [
  562. 'list' => $res,
  563. ]);
  564. }
  565. /**
  566. * 设备_基本资料
  567. * 更新机台设备
  568. */
  569. public function updateMachineDeviceTypes() {
  570. if (!$this->request->isPost()) {
  571. $this->error('非法请求');
  572. }
  573. $params = $this->request->param();
  574. if (empty($params['UniqId'])) {
  575. $this->error('UniqId 参数不能为空');
  576. }
  577. $deviceData = [
  578. // 'sys_sbID' => $params['sys_sbID'],
  579. // '工序' => $params['工序'],
  580. // '设备编号' => $params['设备编号'],
  581. // '生产工序' => $params['生产工序'],
  582. // '设备编组' => $params['设备编组'],
  583. // '组长' => $params['组长'],
  584. 'status' => $params['status'],
  585. ];
  586. $result = \db('设备_基本资料')
  587. ->where('UniqId', $params['UniqId'])
  588. ->where('mod_rq', null)
  589. ->update($deviceData);
  590. if ($result) {
  591. $this->success('设备更新成功');
  592. } else {
  593. $this->error('设备更新失败');
  594. }
  595. }
  596. /**
  597. * 新增设备_基本资料
  598. * 新增机台设备
  599. */
  600. public function addMachineDeviceTypes() {
  601. if (!$this->request->isPost()) {
  602. $this->error('非法请求');
  603. }
  604. $params = $this->request->param();
  605. // 生产工序与工序号的映射
  606. $processMapping = [
  607. '裁剪' => 2,
  608. '车缝' => 3,
  609. '手工' => 4,
  610. '总检' => 6,
  611. '大烫' => 5,
  612. '包装' => 7,
  613. ];
  614. $productionProcess = $params['生产工序'] ?? '';
  615. $UniqId = \db('设备_基本资料')
  616. ->field('UniqId')
  617. ->order('UniqId desc')
  618. ->find();
  619. // 新的设备数据
  620. $deviceData = [
  621. 'UniqId' => $UniqId['UniqId'] + 1,
  622. 'sys_sbID' => $params['sys_sbID'],
  623. '工序' => $processMapping[$productionProcess],
  624. '设备编号' => $params['设备编号'],
  625. '生产工序' => $params['生产工序'],
  626. '设备编组' => $params['设备编组'],
  627. '组长' => $params['组长'],
  628. 'sys_id' => $params['sys_id'],
  629. 'sys_rq' => date('Y-m-d H:i:s'),
  630. 'status' => 1,
  631. ];
  632. $result = \db('设备_基本资料')->fetchSql(true)
  633. ->insert($deviceData);
  634. $list_gd = \db()->query($result);
  635. if ($result) {
  636. $this->success('设备新增成功');
  637. } else {
  638. $this->error('设备新增失败');
  639. }
  640. }
  641. /**
  642. * 订单状态更新
  643. */
  644. public function Apigdstatus() {
  645. if (!$this->request->isPost()) {
  646. $this->error('非法请求');
  647. }
  648. $params = $this->request->param();
  649. $uniqids = explode(',', $params['Uniqid']);
  650. // 判断gd_statu是否为“3-已完工”,只判断一次
  651. $isFinished = $params['gd_statu'] == '已完工';
  652. foreach ($uniqids as $uniqid) {
  653. $uniqid = trim($uniqid);
  654. $updateData = [
  655. 'gd_statu' => $params['gd_statu']
  656. ];
  657. // 如果是“已完工”,加上完工日期
  658. if ($isFinished) {
  659. $updateData['工单完工日期'] = date('Y-m-d H:i:s');
  660. } else {
  661. // 如果不是已完工,清空完工日期
  662. $updateData['工单完工日期'] = null;
  663. }
  664. $ReportSql = \db('工单_基本资料')->where('Uniqid', $uniqid)->fetchSql(true)->update($updateData);
  665. \db()->query($ReportSql);
  666. }
  667. $this->success('订单状态更新成功');
  668. }
  669. /**
  670. * 产品BOM资料
  671. */
  672. public function Apibomlistarr(){
  673. if ($this->request->isGet() === false) {
  674. $this->error('请求错误');
  675. }
  676. $param = $this->request->param();
  677. $page = isset($param['page']) ? (int)$param['page'] : 1; // 默认第1页
  678. $limit = isset($param['limit']) ? (int)$param['limit'] : 50; // 默认每页50条
  679. $where = [];
  680. if (!empty($param['search'])) {
  681. $where['a.订单编号|a.生产款号|a.客户编号|a.款式|b.BOM_物料编码|b.BOM_物料名称|b.物料分类'] = ['like', '%' .$param['search'] . '%'];
  682. }
  683. $bomlist = Db::name('工单_基本资料')->alias('a')
  684. ->field('
  685. a.订单编号 as 订单编号,
  686. a.生产款号 as 生产款号,
  687. a.客户编号 as 客户编号,
  688. a.款式 as 款式,
  689. a.Sys_ID,
  690. c.Sys_rq,
  691. b.物料分类 as 物料分类,
  692. b.BOM_物料名称 as 物料名称,
  693. b.BOM_计划门幅 as 计划门幅,
  694. b.BOM_定额门幅 as 定额门幅,
  695. b.BOM_计划用量 as 计划用料,
  696. b.BOM_实际用量 as 标准用料,
  697. b.BOM_desc as 备注,
  698. c.BOM_物料编码 as 物料编码,
  699. c.BOM_颜色 as 颜色,
  700. d.入仓总量 as 库存总量,
  701. d.领用数量 as 领用数量,
  702. d.库存数量 as 面料结余,
  703. d.退还数量 as 退还数量
  704. ')
  705. ->join('工单_bom资料 b', 'a.订单编号 = b.BOM_工单编号', 'left')
  706. ->join('工单_面料资料 c', 'b.BOM_物料名称 = c.BOM_物料名称 AND b.BOM_工单编号 = c.BOM_工单编号', 'left')
  707. ->join('物料_库存 d', 'c.BOM_物料名称 = d.物料名称 AND c.BOM_物料编码 = d.物料编号', 'left')
  708. ->where($where)
  709. ->orderRaw('CAST(b.Sys_rq AS DATETIME) desc')
  710. ->whereNull('a.Mod_rq')
  711. ->whereNull('b.Mod_rq')
  712. ->whereNull('c.Mod_rq')
  713. ->whereNull('d.Mod_rq')
  714. ->limit(($page - 1) * $limit, $limit)
  715. ->select();
  716. // echo "<pre>";
  717. // print_r($bomlist);
  718. // echo "<pre>";
  719. // 处理数据,去掉计划用料字段的小数点后多余的0
  720. foreach ($bomlist as &$item) {
  721. // 转换为浮点数,去掉无意义的 0
  722. $item['计划用料'] = floatval($item['计划用料']);
  723. }
  724. // 解除引用,防止意外修改
  725. unset($item);
  726. // 使用与实际查询相同的表关联和条件来计算总数
  727. $count = Db::name('工单_基本资料')->alias('a')
  728. ->join('工单_bom资料 b', 'a.订单编号 = b.BOM_工单编号', 'left')
  729. ->join('工单_面料资料 c', 'b.BOM_物料名称 = c.BOM_物料名称 AND b.BOM_工单编号 = c.BOM_工单编号', 'left')
  730. ->join('物料_库存 d', 'c.BOM_物料名称 = d.物料名称 AND c.BOM_物料编码 = d.物料编号', 'left')
  731. ->where($where)
  732. ->whereNull('a.Mod_rq')
  733. ->whereNull('b.Mod_rq')
  734. ->whereNull('c.Mod_rq')
  735. ->whereNull('d.Mod_rq')
  736. ->count();
  737. $data['total'] = $count;
  738. $data['list'] = $bomlist;
  739. $this->success('成功',$data);
  740. }
  741. public function Get_rework(){
  742. if ($this->request->isGet() === false) {
  743. $this->error('请求错误');
  744. }
  745. $param = $this->request->param();
  746. $search = input('search');
  747. $page = input('page');
  748. $limit = input('limit');
  749. $where = [];
  750. if (!empty($param['search'])) {
  751. $where['订单编号|生产款号|问题分类|面料名称|组别'] = ['like', '%' . $search . '%'];
  752. }
  753. $page = isset($param['page']) ? (int)$param['page'] : 1; // 默认第1页
  754. $limit = isset($param['limit']) ? (int)$param['limit'] : 50; // 默认每页50条
  755. // 查询订单问题详情数据
  756. // 获取当前年份
  757. $currentYear = date('Y');
  758. // 统计总记录数(按生产款号和问题分类分组后的总条数)
  759. $subQuery = Db::name('设备_质量汇总')
  760. ->field('生产款号,问题分类')
  761. ->where('状态', 'in', ['次片', '返工'])
  762. ->where('YEAR(Sys_rq)', $currentYear)
  763. ->where($where)
  764. ->group('生产款号, 问题分类')
  765. ->buildSql();
  766. $count = Db::table($subQuery . ' t')
  767. ->count();
  768. // 获取分页数据
  769. $list = Db::name('设备_质量汇总')
  770. ->field('订单编号,生产款号,组别,问题分类, COUNT(*) as 记录数, SUM(数量) as 返工数量,面料名称,状态,颜色,尺码')
  771. ->where('状态', 'in', ['次片', '返工'])
  772. ->where('YEAR(Sys_rq)', $currentYear)
  773. ->where($where)
  774. ->order('Sys_rq desc')
  775. ->group('生产款号, 问题分类')
  776. ->limit(($page - 1) * $limit, $limit)
  777. ->select();
  778. // 格式化订单问题详情数据
  779. $formattedList = [];
  780. foreach ($list as $item) {
  781. $formattedList[] = [
  782. '订单编号' => $item['订单编号'],
  783. '生产款号' => $item['生产款号'],
  784. '面料名称' => $item['面料名称'],
  785. '组别' => $item['组别'],
  786. '状态' => $item['状态'],
  787. '问题分类' => $item['问题分类'],
  788. '颜色' => $item['颜色'],
  789. '尺码' => $item['尺码'],
  790. '返工数量' => intval($item['返工数量'] ?: ($item['记录数'] ?: 0))
  791. ];
  792. }
  793. // 查询问题分类统计排行
  794. $problemStats = Db::name('设备_质量汇总')
  795. ->field('问题分类, COUNT(*) as 问题次数, SUM(数量) as 问题数量')
  796. ->where('状态', 'in', ['次片', '返工'])
  797. ->where('YEAR(Sys_rq)', $currentYear)
  798. ->where($where) // 应用搜索条件
  799. ->group('问题分类')
  800. ->order('问题数量 desc') // 按问题数量降序排序
  801. ->limit(10) // 只取前10个问题分类
  802. ->select();
  803. // 计算问题总数量,用于计算百分比
  804. $totalProblemData = Db::name('设备_质量汇总')
  805. ->field('SUM(数量) as total_quantity')
  806. ->where('状态', 'in', ['次片', '返工'])
  807. ->where('YEAR(Sys_rq)', $currentYear)
  808. ->where($where) // 应用搜索条件
  809. ->find();
  810. $totalProblemQuantity = $totalProblemData['total_quantity'] ?? 1; // 避免除零错误
  811. // 格式化问题分类排行数据,添加百分比占比
  812. $problemRanking = [];
  813. foreach ($problemStats as $index => $item) {
  814. // 计算百分比占比
  815. $percentage = round(($item['问题数量'] / $totalProblemQuantity) * 100, 2);
  816. $problemRanking[] = [
  817. '排名' => $index + 1,
  818. '问题分类' => $item['问题分类'] ?? '未分类',
  819. '问题次数' => intval($item['问题次数'] ?: 0),
  820. '问题数量' => intval($item['问题数量'] ?: 0),
  821. '百分比占比' => $percentage . '%' // 添加百分比占比字段
  822. ];
  823. }
  824. $result = [
  825. 'code' => 0,
  826. 'msg' => '获取订单返工统计数据成功',
  827. 'count' => $count,
  828. 'data' => $formattedList,
  829. 'list' => $problemRanking,
  830. ];
  831. return json($result);
  832. }
  833. }