GluingReport.php 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use think\Db;
  5. use think\Request;
  6. class GluingReport extends Api
  7. {
  8. protected $noNeedLogin = ['*'];
  9. protected $noNeedRight = ['*'];
  10. /**
  11. * 设备角色菜单
  12. * @return void
  13. */
  14. public function getGluingcoleTab()
  15. {
  16. if ($this->request->isGet() === false){
  17. $this->error('请求错误');
  18. }
  19. $data = [];
  20. $sist = ['印后糊盒车间','精品自动化车间','数字化车间'];
  21. $department = \db('设备_基本资料')
  22. ->distinct(true)
  23. ->where('使用部门','in',$sist)
  24. ->where('设备编组','<>','')
  25. ->order('设备编组')
  26. ->column('rtrim(使用部门) as 使用部门');
  27. if (empty($department)){
  28. $this->success('未获取到机台数据');
  29. }
  30. foreach ($department as $value){
  31. $machine = \db('设备_基本资料')
  32. ->where('使用部门',$value)
  33. ->field('rtrim(设备编号) as 设备编号,rtrim(设备名称) as 设备名称')
  34. ->order('设备编号')
  35. ->select();
  36. foreach ($machine as $k=>$v){
  37. $data[rtrim($value)][] = $v['设备编号'].'-->'.$v['设备名称'];
  38. }
  39. }
  40. $this->success('成功',$data);
  41. }
  42. /**
  43. * 设备角色列表
  44. * @return void
  45. * @throws \think\db\exception\DataNotFoundException
  46. * @throws \think\db\exception\ModelNotFoundException
  47. * @throws \think\exception\DbException
  48. */
  49. public function getGluingcoleList()
  50. {
  51. if ($this->request->isGet() === false){
  52. $this->error('请求错误');
  53. }
  54. $param = $this->request->param();
  55. if (empty($param)){
  56. $this->error('参数错误');
  57. }
  58. $list = db('设备_糊盒班组角色')
  59. ->where('jtbh',$param['machine'])
  60. ->select();
  61. if (empty($list)){
  62. $this->error('未找到数据');
  63. }else{
  64. $this->success('成功',$list);
  65. }
  66. }
  67. /**
  68. * 设备角色资料详情
  69. * @return void
  70. * @throws \think\db\exception\DataNotFoundException
  71. * @throws \think\db\exception\ModelNotFoundException
  72. * @throws \think\exception\DbException
  73. */
  74. public function getGluingcoleDetail()
  75. {
  76. if ($this->request->isGet() === false){
  77. $this->error('请求错误');
  78. }
  79. $param = $this->request->param();
  80. if (empty($param)){
  81. $this->error('参数错误');
  82. }
  83. $list = db('设备_糊盒班组角色')
  84. ->where('id',$param['id'])
  85. ->find();
  86. if (empty($list)){
  87. $this->error('未找到数据详情');
  88. }else{
  89. $this->success('成功',$list);
  90. }
  91. }
  92. /**
  93. * 新增机台班组角色
  94. * @return void
  95. */
  96. public function saveGluingcoleDetail(){
  97. if ($this->request->isPost() === false){
  98. $this->error('请求错误');
  99. }
  100. $param = Request::instance()->post();
  101. if (empty($param)){
  102. $this->error('参数错误');
  103. }
  104. $param['sys_rq'] = date('Y-m-d H:i:s',time());
  105. $res = db('设备_糊盒班组角色')->insert($param);
  106. if (empty($res)){
  107. $this->error('新增失败');
  108. }else{
  109. $this->success('新增成功');
  110. }
  111. }
  112. /**
  113. * 修改设备角色资料
  114. * @return void
  115. * @throws \think\Exception
  116. * @throws \think\exception\PDOException
  117. */
  118. public function getGluingcoleDetaiEdit()
  119. {
  120. if ($this->request->isPost() === false){
  121. $this->error('请求错误');
  122. }
  123. $param = Request::instance()->post();
  124. if (empty($param['id'])){
  125. $this->error('参数错误');
  126. }
  127. $id = intval($param['id']);
  128. $param['mod_rq'] = date('Y-m-d H:i:s',time());
  129. unset($param['id']);
  130. $res = db('设备_糊盒班组角色')
  131. ->where('id',$id)
  132. ->update($param);
  133. if ($res === false){
  134. $this->error('修改失败');
  135. }else{
  136. $this->success('修改成功');
  137. }
  138. }
  139. /**
  140. * 设备当前班组角色
  141. * @return void
  142. * @throws \think\Exception
  143. * @throws \think\exception\PDOException
  144. */
  145. public function UpdateGluingcoleStatus()
  146. {
  147. if ($this->request->isGet() === false){
  148. $this->error('请求错误');
  149. }
  150. $param = $this->request->param();
  151. if (empty($param['id']) || empty($param['jtbh'])){
  152. $this->error('参数错误');
  153. }
  154. $updateRes = db('设备_糊盒班组角色')
  155. ->where('jtbh',$param['jtbh'])
  156. ->update(['status' => 0]);
  157. $res = db('设备_糊盒班组角色')
  158. ->where('id',$param['id'])
  159. ->update(['status' => 1]);
  160. if ($updateRes === false || $res === false){
  161. $this->error('更新失败');
  162. }else{
  163. $this->success('更新成功');
  164. }
  165. }
  166. /**
  167. * 设备班组资料列表
  168. * @return void
  169. * @throws \think\db\exception\DataNotFoundException
  170. * @throws \think\db\exception\ModelNotFoundException
  171. * @throws \think\exception\DbException
  172. */
  173. public function getGluingClassLList()
  174. {
  175. if ($this->request->isGet() === false){
  176. $this->error('请求错误');
  177. }
  178. $param = $this->request->param();
  179. if (empty($param)){
  180. $this->error('参数错误');
  181. }
  182. $list = db('设备_糊盒班组资料')
  183. ->where('jtbh',$param['machine'])
  184. ->select();
  185. foreach ($list as $k=>$v){
  186. for ($i = 1; $i <= 15; $i++){
  187. $bh = $v['bh'.$i];
  188. $list[$k]['name'.$i] = '';
  189. if (!empty($bh) && $bh !== ''){
  190. $name = \db('人事_基本资料')
  191. ->where('员工编号',$bh)
  192. ->value('员工姓名');
  193. $list[$k]['name'.$i] = $name;
  194. }
  195. }
  196. }
  197. if (empty($list)){
  198. $this->error('未找到数据');
  199. }else{
  200. $this->success('成功',$list);
  201. }
  202. }
  203. /**
  204. * 获取设备角色数据
  205. * @return void
  206. * @throws \think\db\exception\DataNotFoundException
  207. * @throws \think\db\exception\ModelNotFoundException
  208. * @throws \think\exception\DbException
  209. */
  210. public function getGluingcole()
  211. {
  212. if ($this->request->isGet() === false){
  213. $this->error('请求错误');
  214. }
  215. $param = $this->request->param();
  216. if (empty($param)){
  217. $this->error('参数错误');
  218. }
  219. $list = db('设备_糊盒班组角色')
  220. ->where('jtbh',$param['machine'])
  221. ->where('status',1)
  222. ->find();
  223. if (empty($list)){
  224. $this->error('未找到角色资料');
  225. }else{
  226. $this->success('成功',$list);
  227. }
  228. }
  229. /**
  230. * 新增糊盒机台班组资料
  231. * @return void
  232. */
  233. public function AddGluingClass()
  234. {
  235. if ($this->request->isPost() === false){
  236. $this->error('请求错误');
  237. }
  238. $param = Request::instance()->post();
  239. if (empty($param)){
  240. $this->error('参数错误');
  241. }
  242. $param['sys_rq'] = date('Y-m-d H:i:s',time());
  243. $res = db('设备_糊盒班组资料')->insert($param);
  244. if ($res === false){
  245. $this->error('新增失败');
  246. }else{
  247. $this->success('新增成功');
  248. }
  249. }
  250. /**
  251. * 修改设备糊盒班组资料
  252. * @return void
  253. * @throws \think\Exception
  254. * @throws \think\exception\PDOException
  255. */
  256. public function UpdateGluingClass()
  257. {
  258. if ($this->request->isPost() === false){
  259. $this->error('请求错误');
  260. }
  261. $param = Request::instance()->post();
  262. if (empty($param['id'])){
  263. $this->error('参数错误');
  264. }
  265. $id = intval($param['id']);
  266. $param['mod_rq'] = date('Y-m-d H:i:s',time());
  267. unset($param['id']);
  268. $res = db('设备_糊盒班组资料')
  269. ->where('id',$id)
  270. ->update($param);
  271. if ($res === false){
  272. $this->error('修改失败');
  273. }else{
  274. $this->success('修改成功');
  275. }
  276. }
  277. /**
  278. * 糊盒机台报工
  279. * @return void
  280. * @throws \think\db\exception\BindParamException
  281. * @throws \think\exception\PDOException
  282. */
  283. public function addGluingReportData()
  284. {
  285. // 1. 请求方式验证(严格限制POST请求)
  286. if (!$this->request->isPost()) {
  287. $this->error('仅支持POST请求');
  288. }
  289. // 2. 获取并验证参数(重点适配含#字符的sczl_jtbh字段)
  290. $param = $this->request->post();
  291. // 核心修复:验证规则调整,明确允许#字符,兼容特殊字符
  292. $validate = new \think\Validate([
  293. 'sczl_jtbh' => 'require|regex:/^[\w#\x{4e00}-\x{9fa5}]+$/u', // 允许字母、数字、下划线、#、中文
  294. 'sczl_gdbh' => 'require',
  295. 'sczl_gxmc' => 'require',
  296. 'sys_id' => 'require',
  297. 'sczl_rq' => 'require|dateFormat:Y-m-d H:i:s',
  298. ], [
  299. 'sczl_jtbh.require' => '机组编号不能为空',
  300. 'sczl_jtbh.regex' => '机组编号仅支持字母、数字、下划线、#号和中文',
  301. 'sczl_gdbh.require' => '工单号不能为空',
  302. 'sczl_gxmc.require' => '工序名称不能为空',
  303. 'sys_id.require' => '系统ID不能为空',
  304. 'sczl_rq.require' => '报工日期不能为空',
  305. 'sczl_rq.dateFormat' => '报工日期格式错误(需为Y-m-d H:i:s)',
  306. ]);
  307. // 验证前处理:仅去除前后空格(不影响#字符)
  308. foreach (['sczl_jtbh', 'sczl_gdbh', 'sczl_gxmc', 'sys_id', 'sczl_rq'] as $field) {
  309. if (isset($param[$field]) && is_string($param[$field])) {
  310. $param[$field] = trim($param[$field]); // 只去空格,保留#等特殊字符
  311. }
  312. }
  313. // 执行验证
  314. if (!$validate->check($param)) {
  315. $this->error($validate->getError());
  316. }
  317. if ($this->isEmptyReportPrice($param['price'] ?? null)) {
  318. $resolvedPrice = $this->resolveReportPrice($param);
  319. if ($resolvedPrice !== null) {
  320. $param['price'] = $resolvedPrice;
  321. } else {
  322. unset($param['price']);
  323. }
  324. }
  325. // 3. 事务处理(确保数据一致性)
  326. $currentTime = date('Y-m-d H:i:s');
  327. $tableClass = '糊盒报工班组';
  328. $tableDevice = '设备_糊盒报工资料';
  329. // 4. 构建班组数据(保留#字符,无需额外处理)
  330. $classData = [
  331. 'sys_rq' => $currentTime,
  332. 'jtbh' => $param['sczl_jtbh'], // 直接保留含#的原始值
  333. 'gdbh' => $param['sczl_gdbh'],
  334. 'gxmc' => $param['sczl_gxmc'],
  335. 'sys_id' => $param['sys_id'],
  336. 'sczl_rq' => $param['sczl_rq'],
  337. 'sczl_bzdh' => $param['sczl_bzdh'],
  338. ];
  339. // 处理动态字段(1-30组bh/rate)
  340. $dynamicFields = [];
  341. for ($i = 1; $i <= 30; $i++) {
  342. $dynamicFields['bh' . $i] = isset($param['bh' . $i]) ? $param['bh' . $i] : '';
  343. $dynamicFields['rate' . $i] = isset($param['rate' . $i]) ? $param['rate' . $i] : '';
  344. }
  345. $classData = array_merge($classData, $dynamicFields);
  346. // 5. 保存班组数据(框架会自动处理特殊字符转义,避免SQL注入)
  347. $classId = Db::name($tableClass)->insertGetId($classData);
  348. if (empty($classId)) {
  349. throw new \Exception("{$tableClass}数据保存失败");
  350. }
  351. // 6. 构建设备数据(适配PHP7.2)
  352. $filteredParam = array_filter($param, function ($key) {
  353. return !preg_match('/^(bh|rate)\d+$/', $key);
  354. }, ARRAY_FILTER_USE_KEY);
  355. $deviceData = array_merge([
  356. 'role' => $classId,
  357. 'sys_rq' => $currentTime,
  358. ], $filteredParam);
  359. // 7. 保存设备数据(含#字符的字段会被自动转义,安全插入)
  360. $sql = Db::name($tableDevice)->fetchSql(true)->insert($deviceData);
  361. $saveResult = db()->query($sql);
  362. if ($saveResult !== false) {
  363. $this->success('报工提交成功');
  364. }else{
  365. $this->error('报工提交失败');
  366. }
  367. }
  368. /**
  369. * 糊盒机台报工数据菜单
  370. * @return void
  371. * @throws \think\db\exception\DataNotFoundException
  372. * @throws \think\db\exception\ModelNotFoundException
  373. * @throws \think\exception\DbException
  374. */
  375. public function getTab()
  376. {
  377. if ($this->request->isGet() === false){
  378. $this->error('请求错误');
  379. }
  380. $data = [];
  381. $date = date('Y-m-d 00:00:00',time()-3888000);
  382. $sist = ['印后糊盒车间','精品自动化车间','精品手工车间','数字化车间'];
  383. $department = \db('设备_基本资料')
  384. ->distinct(true)
  385. ->where('使用部门','in',$sist)
  386. ->where('设备编组','<>','')
  387. ->order('设备编组')
  388. ->column('rtrim(使用部门) as 使用部门');
  389. if (empty($department)){
  390. $this->success('未获取到机台数据');
  391. }
  392. $list = \db('设备_糊盒报工资料')
  393. ->field([
  394. 'DISTINCT(sczl_rq)' => '时间',
  395. 'rtrim(sczl_jtbh)' => '机台编号'
  396. ])
  397. ->where('sczl_rq','>',$date)
  398. ->order('sczl_rq desc')
  399. ->select();
  400. foreach ($department as $value){
  401. $machine = \db('设备_基本资料')
  402. ->where('使用部门',$value)
  403. ->field('rtrim(设备编号) as 设备编号,rtrim(设备名称) as 设备名称')
  404. ->order('设备编号')
  405. ->select();
  406. foreach ($machine as $k=>$v){
  407. $data[rtrim($value)][$v['设备编号'].'-->'.$v['设备名称']] = [];
  408. foreach ($list as $kk=>$vv){
  409. if ($v['设备编号'] === $vv['机台编号']){
  410. array_push($data[rtrim($value)][$v['设备编号'].'-->'.$v['设备名称']],date('Y-m-d',strtotime($vv['时间'])));
  411. }
  412. }
  413. }
  414. }
  415. $this->success('成功',$data);
  416. }
  417. /**
  418. * 获取当前生产工单
  419. * @return void
  420. * @throws \think\db\exception\DataNotFoundException
  421. * @throws \think\db\exception\ModelNotFoundException
  422. * @throws \think\exception\DbException
  423. */
  424. public function GetProduction()
  425. {
  426. if (Request::instance()->isGet() == false) {
  427. $this->error('非法请求');
  428. }
  429. $params = Request::instance()->param();
  430. if (!isset($params['machine']) || empty($params['machine'])) {
  431. $this->error('参数错误');
  432. }
  433. $machine = $params['machine'];
  434. $machineCode = \db('dic_lzde')->where('适用机型',$machine)->value('sys_bh');
  435. $data = \db('设备_糊盒报工采集')->where('sczl_jtbh',$machine)->order('UID desc')->find();
  436. if (empty($data)){
  437. $this->success('未找到数据');
  438. }
  439. $list = [];
  440. $list['班组ID'] = $data['班组ID'];
  441. $row = [];
  442. if (!empty($data['sczl_gdbh'])){
  443. $endTime = \db('工单_工艺资料')
  444. ->where('Gy0_gdbh',$data['sczl_gdbh'])
  445. ->where('Gy0_yjno',$data['sczl_yjno'])
  446. ->where('Gy0_gxh',$data['sczl_gxh'])
  447. ->find();
  448. $list['工单编号'] = $data['sczl_gdbh'];
  449. if (!empty($endTime)){
  450. $list['印件号'] = $data['sczl_yjno'];
  451. $name = \db('工单_基本资料')->where('Gd_Gdbh',$data['sczl_gdbh'])->value('成品名称');
  452. $code = \db('工单_基本资料')->where('Gd_Gdbh',$data['sczl_gdbh'])->value('成品代号');
  453. $list['产品名称'] = rtrim($name);
  454. $list['产品代号'] = rtrim($code);
  455. $list['工序名称'] = $data['sczl_gxmc'];
  456. $list['联数'] = $endTime['Gy0_ls'];
  457. }
  458. $list['状态'] = rtrim($data['status']);
  459. $list['开工时间'] = $data['sczl_kgsj'];
  460. }else{
  461. $list['工单编号'] = '';
  462. $list['印件号'] = 0;
  463. $list['产品名称'] = '';
  464. $list['工序名称'] = '';
  465. $list['产品代号'] = '';
  466. $list['状态'] = '';
  467. $list['开工时间'] = '';
  468. $list['联数'] = '';
  469. }
  470. $list['班组编号'] = rtrim($data['sczl_bzbh']);
  471. $idList = explode(',',$data['班组ID']);
  472. foreach ($idList as $k=>$v){
  473. $class = \db('设备_糊盒班组资料')
  474. ->where('id',$v)
  475. ->field("role,rate,bh1,bh2,bh3,bh4,bh5,bh6,bh7,bh8,bh9,bh10,bh11,bh12,bh13,bh14,bh15")
  476. ->find();
  477. if (!empty($class)){
  478. for ($i=1;$i<16;$i++) {
  479. if ($class['bh' . $i] != '' && $class['bh' . $i] != '000000') {
  480. $name = \db('人事_基本资料')->where('员工编号', $class['bh' . $i])->field('rtrim(员工姓名) as 姓名')->find();
  481. $row[] = [
  482. '编号' => $class['bh' . $i],
  483. '姓名' => $name['姓名'],
  484. '比例' => $class['rate'],
  485. '角色' => $class['role'],
  486. ];
  487. }
  488. }
  489. $row = array_values($row);
  490. }
  491. }
  492. $list['班组成员'] = $row;
  493. $list['定额代号'] = $machineCode;
  494. $this->success('成功',$list);
  495. }
  496. /**
  497. * 设置当前工单和当前班组
  498. * @return void
  499. */
  500. public function setMachineTeam()
  501. {
  502. if (Request::instance()->isPost() == false) {
  503. $this->error('非法请求');
  504. }
  505. $params = Request::instance()->post();
  506. if (!isset($params['machine']) || empty($params['machine'] )) {
  507. $this->error('参数不能为空');
  508. }
  509. if (empty($params['team_id']) || empty($params['sczl_bzdh'])){
  510. $this->error('请先选择班组成员');
  511. }
  512. $machine = $params['machine'] . '#';
  513. $data = [];
  514. $data['status'] = $params['status'];
  515. $data['sczl_sj'] = date('Y-m-d H:i:s');
  516. $data['sczl_jtbh'] = $machine;
  517. $data['sczl_gdbh'] = empty($params['order']) ? '':$params['order'];
  518. $data['sczl_yjno'] = empty($params['yjno']) ? '':$params['yjno'];
  519. $data['sczl_gxh'] = empty($params['gy_name']) ? '' : (int)substr($params['gy_name'], 0, 2);
  520. $data['sczl_gxmc'] = empty($params['gy_name']) ? '' : $params['gy_name'];
  521. $data['sczl_bzbh'] = $params['sczl_bzdh'];
  522. $data['班组ID'] = $params['team_id'];
  523. // 获取当前时间
  524. $current_time = time();
  525. // 设置时间范围
  526. $start_time1 = strtotime(date('Y-m-d') . ' 08:30:00');
  527. $end_time1 = strtotime(date('Y-m-d') . ' 20:30:00');
  528. $end_time2 = strtotime(date('Y-m-d') . ' 24:00:00');
  529. $start_time3 = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 08:30:00');
  530. $start_time4 = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 00:00:00');
  531. // 判断当前时间属于哪个时间范围
  532. if ($current_time >= $start_time1 && $current_time <= $end_time1) {
  533. $data['sczl_kgsj'] = date('Y-m-d') . ' 08:30:00';
  534. } elseif ($current_time > $end_time1 && $current_time <= $end_time2) {
  535. $data['sczl_kgsj'] = date('Y-m-d') . ' 20:30:00';
  536. } elseif ($current_time > $end_time1 && $current_time <= $start_time3) {
  537. $data['sczl_kgsj'] = date('Y-m-d', strtotime('+1 day')) . ' 08:30:00';
  538. }elseif ($current_time > $start_time4 && $current_time <= $start_time3){
  539. $data['sczl_kgsj'] = date('Y-m-d') . ' 20:30:00';
  540. }
  541. if (!empty($params['order']) && !empty($params['yjno'])){
  542. $option['Gy0_gdbh'] = $params['order'];
  543. $option['Gy0_yjno'] = $params['yjno'];
  544. $option['Gy0_gxh'] = $data['sczl_gxh'];
  545. $data['任务ID'] = \db('工单_工艺资料')->where($option)->value('UniqId');
  546. }else{
  547. $data['任务ID'] = '';
  548. }
  549. $sql = \db('设备_糊盒报工采集')->fetchSql(true)->insert($data);
  550. $res = Db::query($sql);
  551. if ($res === false) {
  552. $this->error('设置失败');
  553. } else {
  554. $this->success('设置成功');
  555. }
  556. }
  557. /**
  558. * 糊盒设备运行跟踪数据页面显示
  559. * @return void
  560. * @throws \think\db\exception\DataNotFoundException
  561. * @throws \think\db\exception\ModelNotFoundException
  562. * @throws \think\exception\DbException
  563. */
  564. public function getGluingReportDataList()
  565. {
  566. if ($this->request->isGet() === false){
  567. $this->error('请求错误');
  568. }
  569. $params = $this->request->param();
  570. if (empty($params['machine']) || empty($params['day'])){
  571. $this->error('参数错误');
  572. }
  573. $where = [
  574. 'a.sczl_jtbh' => $params['machine'],
  575. 'a.sczl_rq' => ['like',$params['day'].'%']
  576. ];
  577. $field = ['a.sczl_gdbh as 工单编号','a.sczl_gxmc as 工序名称','a.来料数量','a.sczl_cl as 产量',
  578. 'a.sczl_zcfp as 制程废品','a.startTime as 开始时间','a.endTime as 结束时间','a.sczl_ls as 联数','a.sczl_rq as 日期',
  579. 'a.sczl_dedh as 定额代号','a.工价系数','a.保养工时','a.装版工时','a.异常工时','a.异常类型','a.设备运行工时','a.role',
  580. 'a.sys_id as 创建人员','a.sys_rq as 上报时间','a.mod_rq as 修改时间','a.Uid','a.sczl_jtbh as 机台编号','a.price',
  581. 'b.Gd_cpdh as 产品代号','b.Gd_cpmc as 产品名称','a.sczl_bzdh as 班组','a.来料异常'];
  582. $list = \db('设备_糊盒报工资料')
  583. ->alias('a')
  584. ->join('工单_基本资料 b','a.sczl_gdbh = b.Gd_gdbh','left')
  585. ->field($field)
  586. ->where($where)
  587. ->group('a.Uid')
  588. ->select();
  589. if (empty($list)){
  590. $this->error('未找到报工数据');
  591. }
  592. foreach ($list as $key=>$value) {
  593. $list[$key]['class'] = [];
  594. $class = \db('糊盒报工班组')
  595. ->where('id', $value['role'])
  596. ->field("bh1,bh2,bh3,bh4,bh5,bh6,bh7,bh8,bh9,bh10,bh11,bh12,bh13,bh14,bh15,bh16,bh17,bh18,bh19,bh20,bh21,bh22,bh23,
  597. bh24,bh25,bh26,bh27,bh28,bh29,bh30,rate1,rate2,rate3,rate4,rate5,rate6,rate7,rate8,rate9,rate10,rate11,rate12,rate13,rate14,
  598. rate15,rate16,rate17,rate18,rate19,rate20,rate21,rate22,rate23,rate24,rate25,rate26,rate27,rate28,rate29,rate30")
  599. ->find();
  600. if (!empty($class)) {
  601. for ($i = 1; $i <=30; $i++) {
  602. if ($class['bh' . $i] != '' && $class['bh' . $i] != '000000') {
  603. $name = \db('人事_基本资料')->where('员工编号', $class['bh' . $i])->field('rtrim(员工姓名) as 姓名')->find();
  604. $list[$key]['class'][] = [
  605. '编号' => $class['bh' . $i],
  606. '姓名' => $name['姓名'],
  607. '比例' => $class['rate'.$i],
  608. ];
  609. }
  610. }
  611. $list[$key]['class'] = array_values($list[$key]['class']);
  612. }
  613. }
  614. $this->success('成功',$list);
  615. }
  616. /**
  617. * 报工数据详情显示
  618. * @return void
  619. * @throws \think\db\exception\DataNotFoundException
  620. * @throws \think\db\exception\ModelNotFoundException
  621. * @throws \think\exception\DbException
  622. */
  623. public function getGluingReportDataDetail()
  624. {
  625. if ($this->request->isGet() === false){
  626. $this->error('请求错误');
  627. }
  628. $params = $this->request->param();
  629. if(!isset($params['id']) || empty($params['id'])){
  630. $this->error('参数错误');
  631. }
  632. $where = ['Uid'=>$params['id']];
  633. $field = ['a.sczl_gdbh as 工单编号','a.sczl_gxmc as 工序名称','a.来料数量','a.sczl_cl as 产量',
  634. 'a.sczl_zcfp as 制程废品','a.startTime as 开始时间','a.endTime as 结束时间','a.sczl_ls as 联数','a.sczl_rq as 日期',
  635. 'a.sczl_dedh as 定额代号','a.工价系数','a.保养工时','a.装版工时','a.异常工时','a.异常类型','a.设备运行工时','a.role',
  636. 'a.sys_id as 创建人员','a.sys_rq as 上报时间','a.mod_rq as 修改时间','a.Uid','a.sczl_jtbh as 机台编号','a.price',
  637. 'b.Gd_cpdh as 产品代号','b.Gd_cpmc as 产品名称','a.sczl_bzdh as 班组','a.来料异常'];
  638. $list = \db('设备_糊盒报工资料')
  639. ->alias('a')
  640. ->join('工单_基本资料 b','a.sczl_gdbh = b.Gd_gdbh','left')
  641. ->where($where)
  642. ->field($field)
  643. ->find();
  644. $list['class'] = [];
  645. $class = \db('糊盒报工班组')
  646. ->where('id', $list['role'])
  647. ->field("bh1,bh2,bh3,bh4,bh5,bh6,bh7,bh8,bh9,bh10,bh11,bh12,bh13,bh14,bh15,bh16,bh17,bh18,bh19,bh20,bh21,bh22,bh23,
  648. bh24,bh25,bh26,bh27,bh28,bh29,bh30,rate1,rate2,rate3,rate4,rate5,rate6,rate7,rate8,rate9,rate10,rate11,rate12,rate13,rate14,
  649. rate15,rate16,rate17,rate18,rate19,rate20,rate21,rate22,rate23,rate24,rate25,rate26,rate27,rate28,rate29,rate30")
  650. ->find();
  651. if (!empty($class)) {
  652. for ($i = 1; $i <=30; $i++) {
  653. if ($class['bh' . $i] != '' && $class['bh' . $i] != '000000') {
  654. $name = \db('人事_基本资料')->where('员工编号', $class['bh' . $i])->field('rtrim(员工姓名) as 姓名')->find();
  655. $list['class'][] = [
  656. '编号' => $class['bh' . $i],
  657. '姓名' => $name['姓名'],
  658. '比例' => $class['rate'.$i],
  659. ];
  660. }
  661. }
  662. $list['class'] = array_values($list['class']);
  663. }
  664. $this->success('成功',$list);
  665. }
  666. /**
  667. * 修改糊盒班组报工资料
  668. * @return void
  669. * @throws \think\Exception
  670. * @throws \think\db\exception\BindParamException
  671. * @throws \think\exception\PDOException
  672. */
  673. public function getGluingReportDetailUpdate()
  674. {
  675. if ($this->request->isPost() === false){
  676. $this->error('请求错误');
  677. }
  678. $param = Request::instance()->post();
  679. if(!isset($param['id']) || empty($param['id'])){
  680. $this->error('参数错误');
  681. }
  682. $id = $param['id'];
  683. $role = $param['role'];
  684. unset($param['id']);
  685. // 核心修复:验证规则调整,明确允许#字符,兼容特殊字符
  686. $validate = new \think\Validate([
  687. 'sczl_jtbh' => 'require|regex:/^[\w#\x{4e00}-\x{9fa5}]+$/u', // 允许字母、数字、下划线、#、中文
  688. 'sczl_gdbh' => 'require',
  689. 'sczl_gxmc' => 'require',
  690. 'sczl_rq' => 'require|dateFormat:Y-m-d H:i:s',
  691. ], [
  692. 'sczl_jtbh.require' => '机组编号不能为空',
  693. 'sczl_jtbh.regex' => '机组编号仅支持字母、数字、下划线、#号和中文',
  694. 'sczl_gdbh.require' => '工单号不能为空',
  695. 'sczl_gxmc.require' => '工序名称不能为空',
  696. 'sczl_rq.require' => '报工日期不能为空',
  697. 'sczl_rq.dateFormat' => '报工日期格式错误(需为Y-m-d H:i:s)',
  698. ]);
  699. // 验证前处理:仅去除前后空格(不影响#字符)
  700. foreach (['sczl_jtbh', 'sczl_gdbh', 'sczl_gxmc', 'sczl_rq'] as $field) {
  701. if (isset($param[$field]) && is_string($param[$field])) {
  702. $param[$field] = trim($param[$field]); // 只去空格,保留#等特殊字符
  703. }
  704. }
  705. // 执行验证
  706. if (!$validate->check($param)) {
  707. $this->error($validate->getError());
  708. }
  709. // 3. 事务处理(确保数据一致性)
  710. $currentTime = date('Y-m-d H:i:s');
  711. $tableClass = '糊盒报工班组';
  712. $tableDevice = '设备_糊盒报工资料';
  713. // 4. 构建班组数据(保留#字符,无需额外处理)
  714. $classData = [
  715. 'jtbh' => $param['sczl_jtbh'], // 直接保留含#的原始值
  716. 'gdbh' => $param['sczl_gdbh'],
  717. 'gxmc' => $param['sczl_gxmc'],
  718. 'sczl_rq' => $param['sczl_rq'],
  719. 'sczl_bzdh' => $param['sczl_bzdh'],
  720. ];
  721. // 处理动态字段(1-30组bh/rate)
  722. $dynamicFields = [];
  723. for ($i = 1; $i <= 30; $i++) {
  724. $dynamicFields['bh' . $i] = isset($param['bh' . $i]) ? $param['bh' . $i] : '';
  725. $dynamicFields['rate' . $i] = isset($param['rate' . $i]) ? $param['rate' . $i] : '';
  726. }
  727. $classData = array_merge($classData, $dynamicFields);
  728. // 5. 保存班组数据(框架会自动处理特殊字符转义,避免SQL注入)
  729. $classId = Db::name($tableClass)->where('id',$role)->update($classData);
  730. // 6. 构建设备数据(适配PHP7.2)
  731. $filteredParam = array_filter($param, function ($key) {
  732. return !preg_match('/^(bh|rate)\d+$/', $key);
  733. }, ARRAY_FILTER_USE_KEY);
  734. $deviceData = array_merge([
  735. 'mod_rq' => $currentTime,
  736. ], $filteredParam);
  737. // 7. 保存设备数据(含#字符的字段会被自动转义,安全插入)
  738. $sql = Db::name($tableDevice)->where('Uid',$id)->fetchSql(true)->update($deviceData);
  739. $saveResult = db()->query($sql);
  740. if ($saveResult !== false) {
  741. $this->success('修改成功');
  742. }else{
  743. $this->error('修改失败');
  744. }
  745. }
  746. /**
  747. * 修改报工数据班组
  748. * @return void
  749. * @throws \think\Exception
  750. * @throws \think\exception\PDOException
  751. */
  752. public function UpdateGluingReportClass()
  753. {
  754. if ($this->request->isPost() === false){
  755. $this->error('请求错误');
  756. }
  757. $params = Request::instance()->post();
  758. if(!isset($params['id']) || empty($params['id'])){
  759. $this->error('参数错误');
  760. }
  761. $id = $params['id'];
  762. $data['role'] = $params['role'];
  763. $res = \db('设备_糊盒报工资料')->where('Uid',$id)->update($data);
  764. if ($res === false) {
  765. $this->error('修改失败');
  766. }else{
  767. $this->success('修改成功');
  768. }
  769. }
  770. /**
  771. * 当班产量
  772. * @return void
  773. * @throws \think\db\exception\DataNotFoundException
  774. * @throws \think\db\exception\ModelNotFoundException
  775. * @throws \think\exception\DbException
  776. */
  777. public function GluingReportList()
  778. {
  779. if ($this->request->isGet() === false){
  780. $this->error('请求错误');
  781. }
  782. $params = $this->request->param();
  783. if (!isset($params['machine']) || empty($params['machine'])){
  784. $this->error('参数错误');
  785. }
  786. $machine = $params['machine'];
  787. $sczlTime = date('Y-m-d H:i:s',time());
  788. if ($sczlTime>date('Y-m-d 00:00:00') && $sczlTime<date('Y-m-d 08:30:00')){
  789. $time = date('Y-m-d 00:00:00',time()-86400);
  790. }else{
  791. $time = date('Y-m-d 00:00:00');
  792. }
  793. $where = [
  794. 'sczl_jtbh' => $machine,
  795. 'sczl_rq' => $time,
  796. ];
  797. $field = 'rtrim(sczl_gdbh) as 工单编号,rtrim(sczl_yjno) as yjno,rtrim(sczl_dedh) as dedh,rtrim(sczl_gxmc) as gxmc,
  798. rtrim(sczl_cl) as 产量,rtrim(sczl_zcfp) as 制程废品,rtrim(装版工时) as 装版工时,rtrim(保养工时) as 保养工时,
  799. rtrim(异常工时) as 异常工时,rtrim(设备运行工时) as 通电工时,startTime,endTime,Uid,rtrim(sczl_ls) as ls,来料数量,来料异常';
  800. $list = \db('设备_糊盒报工资料')->where($where)->field($field)->order('Uid desc')->select();
  801. if (!empty($list)){
  802. foreach ($list as $k=>$v){
  803. $name = \db('工单_印件资料')->where('Yj_Gdbh',$v['工单编号'])->where('yj_Yjno',$v['yjno'])->field('rtrim(yj_yjmc) as cpmc')->find();
  804. if ($v['yjno']<10){
  805. $list[$k]['yjno'] = '0'.$v['yjno'];
  806. }
  807. $list[$k]['印件及工序'] = $list[$k]['yjno'].'-'.$v['gxmc'];
  808. $list[$k]['生产时间段'] = substr($v['startTime'],5,5).' '.substr($v['startTime'],11,5).'<-->'.substr($v['endTime'],5,5).' '.substr($v['endTime'],11,5);
  809. $list[$k]['产品名称'] = $name['cpmc'];
  810. }
  811. }
  812. $this->success('成功',$list);
  813. }
  814. /**
  815. * 工单查询
  816. * @return void
  817. * @throws \think\db\exception\DataNotFoundException
  818. * @throws \think\db\exception\ModelNotFoundException
  819. * @throws \think\exception\DbException
  820. */
  821. public function getWorkOrderList()
  822. {
  823. if ($this->request->isGet() === false){
  824. $this->error('请求错误');
  825. }
  826. $params = $this->request->param();
  827. if (!isset($params['search']) || empty($params['search'])){
  828. $this->error('参数错误');
  829. }
  830. $search = $params['search'];
  831. $list = \db('工单_基本资料')
  832. ->where('Gd_gdbh|Gd_cpmc','like','%'.$search.'%')
  833. ->field('Gd_gdbh as 工单编号,Gd_cpdh as 产品代号,Gd_cpmc as 产品名称')
  834. ->order('Gd_gdbh desc')
  835. ->select();
  836. if (empty($list)){
  837. $this->error('未找到数据');
  838. }else{
  839. $this->success('成功',$list);
  840. }
  841. }
  842. /**
  843. * 查询机台编号
  844. * @return void
  845. */
  846. public function getMachineList()
  847. {
  848. if ($this->request->isGet() === false){
  849. $this->error('请求错误');
  850. }
  851. $params = $this->request->param();
  852. if (!isset($params['search']) || empty($params['search'])){
  853. $this->error('参数错误');
  854. }
  855. $search = $params['search'];
  856. $list = \db('设备_基本资料')
  857. ->where('使用部门',$search)
  858. ->order('设备编号')
  859. ->column('设备名称','设备编号');
  860. if (empty($list)){
  861. $this->error('未找到数据');
  862. }else{
  863. $this->success('成功',$list);
  864. }
  865. }
  866. /**
  867. * 查询工艺名称
  868. * @return void
  869. * @throws \think\db\exception\DataNotFoundException
  870. * @throws \think\db\exception\ModelNotFoundException
  871. * @throws \think\exception\DbException
  872. */
  873. public function gitProcessList()
  874. {
  875. if ($this->request->isGet() === false){
  876. $this->error('请求错误');
  877. }
  878. $params = $this->request->param();
  879. if (!isset($params['search']) || empty($params['search'])){
  880. $this->error('参数错误');
  881. }
  882. $search = $params['search'];
  883. $list = \db('erp_常用字典')
  884. ->where('分类','糊盒工艺')
  885. ->where('名称','like','%'.$search.'%')
  886. ->field('名称')
  887. ->select();
  888. $data = [];
  889. if (empty($list)){
  890. $this->error('未找到工艺数据');
  891. }
  892. foreach ($list as $k=>$v){
  893. $name = explode('_',$v['名称']);
  894. $data[] = $name[2];
  895. }
  896. $this->success('成功',$data);
  897. }
  898. //最新糊盒班组查询
  899. public function classifyList()
  900. {
  901. // 1. 请求方法验证
  902. if (!$this->request->isGet()) {
  903. $this->error('请使用GET请求');
  904. }
  905. // 2. 参数验证
  906. $params = $this->request->param();
  907. // 验证必需参数
  908. $requiredParams = ['sczl_jtbh', 'sczl_bzdh'];
  909. foreach ($requiredParams as $param) {
  910. if (empty($params[$param] ?? null)) {
  911. $this->error("缺少必要参数: {$param}");
  912. }
  913. }
  914. $jtbh = trim($params['sczl_jtbh']);
  915. $bzdh = trim($params['sczl_bzdh']);
  916. // 3. 查询糊盒报工资料
  917. $role = \db('设备_糊盒报工资料')
  918. ->where('sczl_jtbh', $jtbh)
  919. ->where('sczl_bzdh', $bzdh)
  920. ->order('Uid', 'desc')
  921. ->value('role');
  922. if (empty($role)) {
  923. $this->error('未找到对应的报工班组信息');
  924. }
  925. // 4. 动态生成字段列表
  926. $fields = [];
  927. for ($i = 1; $i <= 30; $i++) {
  928. $fields[] = "bh{$i}";
  929. $fields[] = "rate{$i}";
  930. }
  931. // 5. 查询班组信息
  932. $class = \db('糊盒报工班组')
  933. ->where('id', $role)
  934. ->field($fields)
  935. ->find();
  936. if (empty($class)) {
  937. $this->error('班组信息不存在');
  938. }
  939. // 6. 处理班组成员信息
  940. $members = [];
  941. $employeeIds = [];
  942. // 收集所有有效的员工编号
  943. for ($i = 1; $i <= 30; $i++) {
  944. $bh = $class["bh{$i}"] ?? '';
  945. $rate = $class["rate{$i}"] ?? 0;
  946. // 验证员工编号是否有效
  947. $bh = trim($bh);
  948. if (!empty($bh) && $bh !== '000000') {
  949. $employeeIds[$bh] = [
  950. 'index' => $i,
  951. 'rate' => $rate
  952. ];
  953. }
  954. }
  955. // 如果有有效的员工编号,批量查询员工信息
  956. if (!empty($employeeIds)) {
  957. $employeeNames = [];
  958. $ids = array_keys($employeeIds);
  959. // 批量查询员工信息(减少数据库查询次数)
  960. $result = \db('人事_基本资料')
  961. ->whereIn('员工编号', $ids)
  962. ->field('员工编号, rtrim(员工姓名) as 姓名')
  963. ->select();
  964. foreach ($result as $item) {
  965. $employeeNames[$item['员工编号']] = $item['姓名'];
  966. }
  967. // 组装返回数据
  968. foreach ($employeeIds as $employeeId => $info) {
  969. $members[] = [
  970. '编号' => $employeeId,
  971. '姓名' => $employeeNames[$employeeId] ?? '未知',
  972. '比例' => $info['rate']
  973. ];
  974. }
  975. }
  976. $this->success('获取成功', array_values($members));
  977. }
  978. /**
  979. * 判断报工单价是否为空
  980. * @param mixed $price
  981. * @return bool
  982. */
  983. protected function isEmptyReportPrice($price)
  984. {
  985. if ($price === null || $price === '') {
  986. return true;
  987. }
  988. if (is_string($price) && trim($price) === '') {
  989. return true;
  990. }
  991. return is_numeric($price) && (float)$price == 0;
  992. }
  993. /**
  994. * 报工时自动解析单价
  995. * @param array $param
  996. * @return float|null
  997. */
  998. protected function resolveReportPrice(array $param)
  999. {
  1000. $machine = trim($param['sczl_jtbh']);
  1001. $gxmc = trim((string)($param['sczl_gxmc'] ?? $param['gxmc'] ?? ''));
  1002. $count = $this->extractManualProcessCountSilent($param);
  1003. $processText = $this->resolveManualProcessText($machine, $gxmc);
  1004. if ($processText !== '') {
  1005. $manualPrice = $this->resolveManualProcessPriceSilent($processText, $count);
  1006. if ($manualPrice !== null) {
  1007. return $manualPrice;
  1008. }
  1009. }
  1010. if (!$this->isManualMachineId($machine)) {
  1011. $machinePrices = $this->collectMachinePriceValues($machine);
  1012. if (!empty($machinePrices)) {
  1013. return (float)$machinePrices[0];
  1014. }
  1015. }
  1016. $aiService = new Aicompute();
  1017. $rates = $aiService->fetchWorkshopRatesByMachine($machine);
  1018. if (empty($rates)) {
  1019. return null;
  1020. }
  1021. $productName = db('工单_基本资料')
  1022. ->where('Gd_gdbh', trim($param['sczl_gdbh']))
  1023. ->value('Gd_cpmc');
  1024. $productName = $productName ? trim($productName) : '';
  1025. if ($productName !== '') {
  1026. $matched = $aiService->matchWorkshopRateByProductName($rates, $productName);
  1027. if (!empty($matched)) {
  1028. return (float)$matched['piece_price'];
  1029. }
  1030. }
  1031. $aiPrice = $aiService->resolvePiecePriceByAi(trim($param['sczl_gdbh']), $machine);
  1032. if ($aiPrice !== null) {
  1033. return $aiPrice;
  1034. }
  1035. return (float)$rates[0]['piece_price'];
  1036. }
  1037. /**
  1038. * 判断是否手工工序 machine_id
  1039. * @param string $machine
  1040. * @return bool
  1041. */
  1042. protected function isManualMachineId($machine)
  1043. {
  1044. static $manualIds = ['手工割围条', '手工打孔', '手工拆片', '手工贴片', '手工贴磁铁'];
  1045. return in_array(trim((string)$machine), $manualIds, true);
  1046. }
  1047. /**
  1048. * 从机台编号/工序名称中识别手工工序文本
  1049. * @param string $machine
  1050. * @param string $gxmc
  1051. * @return string
  1052. */
  1053. protected function resolveManualProcessText($machine, $gxmc)
  1054. {
  1055. if ($this->isManualMachineId($machine)) {
  1056. return trim($machine);
  1057. }
  1058. $keywords = ['割围条', '打孔', '拆片', '贴磁铁', '贴片'];
  1059. foreach ([$gxmc, $machine] as $text) {
  1060. $text = trim((string)$text);
  1061. if ($text === '') {
  1062. continue;
  1063. }
  1064. foreach ($keywords as $keyword) {
  1065. if (strpos($text, $keyword) !== false) {
  1066. return $text;
  1067. }
  1068. }
  1069. }
  1070. return '';
  1071. }
  1072. /**
  1073. * 收集机台单价列表
  1074. * @param string $machine
  1075. * @return array
  1076. */
  1077. protected function collectMachinePriceValues($machine)
  1078. {
  1079. $list = db('machine_price')
  1080. ->where('machine_id', $machine)
  1081. ->field('price1,price2,price3,price4,price5,price6,price7,price8,price9,price10')
  1082. ->select();
  1083. $result = [];
  1084. foreach ($list as $item) {
  1085. foreach ($item as $value) {
  1086. if ($value !== '' && $value !== null) {
  1087. $result[] = $value;
  1088. }
  1089. }
  1090. }
  1091. return $result;
  1092. }
  1093. /**
  1094. * 静默解析手工工序单价(报工场景,不中断请求)
  1095. * @param string $gxmc
  1096. * @param int|null $count
  1097. * @return float|null
  1098. */
  1099. protected function resolveManualProcessPriceSilent($gxmc, $count)
  1100. {
  1101. if (strpos($gxmc, '割围条') !== false) {
  1102. $row = db('machine_price')->where('machine_id', '手工割围条')->find();
  1103. return $row ? (float)$row['price1'] : null;
  1104. }
  1105. if (strpos($gxmc, '打孔') !== false) {
  1106. if ($count === null) {
  1107. return null;
  1108. }
  1109. return $this->resolvePunchHolePrice($count);
  1110. }
  1111. if (strpos($gxmc, '拆片') !== false) {
  1112. $rows = db('machine_price')->where('machine_id', '手工拆片')->select();
  1113. if (empty($rows)) {
  1114. return null;
  1115. }
  1116. return $this->resolveManualStripPriceSilent($rows, $gxmc, $count);
  1117. }
  1118. if (strpos($gxmc, '贴磁铁') !== false) {
  1119. return $this->resolveManualCountPriceFromDb('手工贴磁铁', $count, false);
  1120. }
  1121. if (strpos($gxmc, '贴片') !== false) {
  1122. return $this->resolveManualCountPriceFromDb('手工贴片', $count, false);
  1123. }
  1124. $row = db('machine_price')
  1125. ->where('machine_id', $gxmc)
  1126. ->whereOr('machine_name', 'like', '%' . $gxmc . '%')
  1127. ->find();
  1128. return $row ? (float)$row['price1'] : null;
  1129. }
  1130. /**
  1131. * 静默提取孔数/拼数
  1132. * @param array $params
  1133. * @return int|null
  1134. */
  1135. protected function extractManualProcessCountSilent(array $params)
  1136. {
  1137. foreach (['count', '孔数', '拼数', 'hole_count', 'piece_count'] as $field) {
  1138. if (!isset($params[$field]) || $params[$field] === '') {
  1139. continue;
  1140. }
  1141. if (!is_numeric($params[$field]) || (int)$params[$field] != $params[$field] || (int)$params[$field] <= 0) {
  1142. continue;
  1143. }
  1144. return (int)$params[$field];
  1145. }
  1146. return null;
  1147. }
  1148. /**
  1149. * 静默解析手工拆片单价
  1150. * @param array $rows
  1151. * @param string $gxmc
  1152. * @param int|null $count
  1153. * @return float|null
  1154. */
  1155. protected function resolveManualStripPriceSilent(array $rows, $gxmc, $count)
  1156. {
  1157. $gxmc = trim($gxmc);
  1158. if ($gxmc === '手工拆片' || $gxmc === '拆片') {
  1159. if ($count === null) {
  1160. return null;
  1161. }
  1162. return $this->resolveDefaultStripPriceByCount($count);
  1163. }
  1164. if ($gxmc !== '') {
  1165. $row = $this->matchManualPriceRow($rows, $gxmc);
  1166. if (empty($row)) {
  1167. return null;
  1168. }
  1169. return $this->calculateStripPriceByRowSilent($row, $count);
  1170. }
  1171. if ($count === null) {
  1172. return null;
  1173. }
  1174. return $this->resolveDefaultStripPriceByCount($count);
  1175. }
  1176. /**
  1177. * 静默计算拆片规格单价
  1178. * @param array $row
  1179. * @param int|null $count
  1180. * @return float|null
  1181. */
  1182. protected function calculateStripPriceByRowSilent(array $row, $count)
  1183. {
  1184. $name = $row['machine_name'];
  1185. $basePrice = (float)$row['price1'];
  1186. if (strpos($name, '1-4拼(特种纸') !== false) {
  1187. if ($count === null) {
  1188. return null;
  1189. }
  1190. if ($count <= 4) {
  1191. return $basePrice;
  1192. }
  1193. return floatval(number_format($basePrice + ($count - 4) * 0.001, 4, '.', ''));
  1194. }
  1195. if (strpos($name, '1-4拼(小盒二次拆片') !== false) {
  1196. if ($count === null) {
  1197. return null;
  1198. }
  1199. if ($count === 8) {
  1200. return 0.01;
  1201. }
  1202. if ($count === 10) {
  1203. return 0.012;
  1204. }
  1205. return $basePrice;
  1206. }
  1207. if (strpos($name, '5-6拼(小盒二次拆片') !== false) {
  1208. return $basePrice;
  1209. }
  1210. if (strpos($name, '6拼及以上') !== false) {
  1211. return $basePrice;
  1212. }
  1213. if (preg_match('/^(\d+)拼/u', $name) && $count === null) {
  1214. return null;
  1215. }
  1216. return $basePrice;
  1217. }
  1218. /**
  1219. * 获取机台报工单价数据
  1220. * 参数:machine(机台编号)、gxmc(工序名称)、count(孔数/拼数,纯数字)
  1221. * 优先按机台编号查询;查不到则按手工工序(gxmc + count)匹配单价
  1222. * @return void
  1223. * @throws \think\db\exception\DataNotFoundException
  1224. * @throws \think\db\exception\ModelNotFoundException
  1225. * @throws \think\exception\DbException
  1226. */
  1227. public function getMachinePriceData()
  1228. {
  1229. if ($this->request->isGet() === false) {
  1230. $this->error('请求错误');
  1231. }
  1232. $params = $this->request->param();
  1233. if (!isset($params['machine']) || $params['machine'] === '') {
  1234. $this->error('参数错误');
  1235. }
  1236. $machine = trim($params['machine']);
  1237. $gxmc = trim((string)($params['gxmc'] ?? $params['sczl_gxmc'] ?? ''));
  1238. $processText = $this->resolveManualProcessText($machine, $gxmc);
  1239. if ($processText !== '') {
  1240. $price = $this->resolveManualProcessPriceByGxmc($processText, $params);
  1241. if ($price !== null) {
  1242. $this->success('获取成功', [$price]);
  1243. }
  1244. }
  1245. if (!$this->isManualMachineId($machine)) {
  1246. $list = db('machine_price')
  1247. ->where('machine_id', $machine)
  1248. ->field('price1,price2,price3,price4,price5,price6,price7,price8,price9,price10')
  1249. ->select();
  1250. $result = [];
  1251. foreach ($list as $item) {
  1252. foreach ($item as $value) {
  1253. if ($value !== '' && $value !== null) {
  1254. $result[] = $value;
  1255. }
  1256. }
  1257. }
  1258. if (!empty($result)) {
  1259. $this->success('获取成功', $result);
  1260. }
  1261. }
  1262. if ($processText === '') {
  1263. $this->error('未找到机台单价,请传入工序名称');
  1264. }
  1265. $this->error('未找到匹配的单价');
  1266. }
  1267. /**
  1268. * 按工序名称解析手工工序单价
  1269. * @param string $gxmc 工序名称
  1270. * @param array $params count=孔数/拼数(纯数字)
  1271. * @return float|null
  1272. */
  1273. protected function resolveManualProcessPriceByGxmc($gxmc, array $params)
  1274. {
  1275. $count = $this->extractManualProcessCount($params);
  1276. if (strpos($gxmc, '割围条') !== false) {
  1277. $row = db('machine_price')->where('machine_id', '手工割围条')->find();
  1278. return $row ? (float)$row['price1'] : null;
  1279. }
  1280. if (strpos($gxmc, '打孔') !== false) {
  1281. if ($count === null) {
  1282. $this->error('请传入孔数(纯数字)');
  1283. }
  1284. return $this->resolvePunchHolePrice($count);
  1285. }
  1286. if (strpos($gxmc, '拆片') !== false) {
  1287. $rows = db('machine_price')->where('machine_id', '手工拆片')->select();
  1288. if (empty($rows)) {
  1289. return null;
  1290. }
  1291. return $this->resolveManualStripPrice($rows, $gxmc, $count);
  1292. }
  1293. if (strpos($gxmc, '贴磁铁') !== false) {
  1294. return $this->resolveManualCountPriceFromDb('手工贴磁铁', $count, true);
  1295. }
  1296. if (strpos($gxmc, '贴片') !== false) {
  1297. return $this->resolveManualCountPriceFromDb('手工贴片', $count, true);
  1298. }
  1299. // 其他手工工序:按 machine_id 或 machine_name 匹配
  1300. $row = db('machine_price')
  1301. ->where('machine_id', $gxmc)
  1302. ->whereOr('machine_name', 'like', '%' . $gxmc . '%')
  1303. ->find();
  1304. return $row ? (float)$row['price1'] : null;
  1305. }
  1306. /**
  1307. * 按拼数查询手工工序单价(machine_name 存拼数)
  1308. * @param string $machineId
  1309. * @param int|null $count
  1310. * @param bool $errorOnMissingCount
  1311. * @return float|null
  1312. */
  1313. protected function resolveManualCountPriceFromDb($machineId, $count, $errorOnMissingCount = false)
  1314. {
  1315. if ($count === null) {
  1316. if ($errorOnMissingCount) {
  1317. $this->error('请传入拼数(纯数字)');
  1318. }
  1319. return null;
  1320. }
  1321. $row = db('machine_price')
  1322. ->where('machine_id', $machineId)
  1323. ->where('machine_name', (string)$count)
  1324. ->find();
  1325. return $row ? (float)$row['price1'] : null;
  1326. }
  1327. /**
  1328. * 提取孔数/拼数(前端传入纯数字)
  1329. * @param array $params
  1330. * @return int|null
  1331. */
  1332. protected function extractManualProcessCount(array $params)
  1333. {
  1334. return $this->extractManualProcessCountSilent($params);
  1335. }
  1336. /**
  1337. * 提取孔数/拼数(前端传入纯数字,缺失时报错)
  1338. * @param array $params
  1339. * @return int
  1340. */
  1341. protected function requireManualProcessCount(array $params)
  1342. {
  1343. $count = $this->extractManualProcessCountSilent($params);
  1344. if ($count === null) {
  1345. $this->error('孔数/拼数必须为大于0的整数');
  1346. }
  1347. return $count;
  1348. }
  1349. /**
  1350. * 手工打孔单价(按孔数区间)
  1351. * @param int $holeCount
  1352. * @return float
  1353. */
  1354. protected function resolvePunchHolePrice($holeCount)
  1355. {
  1356. $holeCount = (int)$holeCount;
  1357. if ($holeCount === 1) {
  1358. return 0.0055;
  1359. }
  1360. if ($holeCount >= 2 && $holeCount <= 4) {
  1361. return 0.007;
  1362. }
  1363. if ($holeCount >= 5 && $holeCount <= 8) {
  1364. return 0.012;
  1365. }
  1366. if ($holeCount >= 9 && $holeCount <= 12) {
  1367. return 0.016;
  1368. }
  1369. if ($holeCount >= 13 && $holeCount <= 18) {
  1370. return 0.025;
  1371. }
  1372. return floatval(number_format(0.025 + ($holeCount - 18) * 0.001, 4, '.', ''));
  1373. }
  1374. /**
  1375. * 手工拆片单价(按规格名称 + 拼数)
  1376. * @param array $rows
  1377. * @param string $gxmc 工序规格名称(文字)
  1378. * @param int|null $count 拼数(纯数字)
  1379. * @return float|null
  1380. */
  1381. protected function resolveManualStripPrice(array $rows, $gxmc, $count)
  1382. {
  1383. $gxmc = trim($gxmc);
  1384. // 通用拆片工序,仅按拼数数字匹配默认单价
  1385. if ($gxmc === '手工拆片' || $gxmc === '拆片') {
  1386. if ($count === null) {
  1387. $this->error('请传入拼数(纯数字)');
  1388. }
  1389. return $this->resolveDefaultStripPriceByCount($count);
  1390. }
  1391. if ($gxmc !== '') {
  1392. $row = $this->matchManualPriceRow($rows, $gxmc);
  1393. if (empty($row)) {
  1394. return null;
  1395. }
  1396. return $this->calculateStripPriceByRow($row, $count);
  1397. }
  1398. if ($count === null) {
  1399. $this->error('请传入拼数(纯数字)');
  1400. }
  1401. return $this->resolveDefaultStripPriceByCount($count);
  1402. }
  1403. /**
  1404. * 默认拆片单价(1.0厚以上灰白板,按拼数数字匹配)
  1405. * @param int $count
  1406. * @return float
  1407. */
  1408. protected function resolveDefaultStripPriceByCount($count)
  1409. {
  1410. $prices = [
  1411. 1 => 0.008,
  1412. 2 => 0.01,
  1413. 3 => 0.013,
  1414. 4 => 0.017,
  1415. 5 => 0.022,
  1416. 6 => 0.028,
  1417. ];
  1418. $pieceCount = min((int)$count, 6);
  1419. return $prices[$pieceCount];
  1420. }
  1421. /**
  1422. * 按 machine_name 匹配手工单价行
  1423. * @param array $rows
  1424. * @param string $gxmc
  1425. * @return array|null
  1426. */
  1427. protected function matchManualPriceRow(array $rows, $gxmc)
  1428. {
  1429. $gxmc = trim($gxmc);
  1430. foreach ($rows as $row) {
  1431. if ($row['machine_name'] === $gxmc) {
  1432. return $row;
  1433. }
  1434. }
  1435. $best = null;
  1436. $bestLen = 0;
  1437. foreach ($rows as $row) {
  1438. $name = $row['machine_name'];
  1439. if (strpos($name, $gxmc) !== false || strpos($gxmc, $name) !== false) {
  1440. $len = mb_strlen($name);
  1441. if ($len > $bestLen) {
  1442. $best = $row;
  1443. $bestLen = $len;
  1444. }
  1445. }
  1446. }
  1447. return $best;
  1448. }
  1449. /**
  1450. * 根据拆片规格行及拼数计算单价
  1451. * @param array $row
  1452. * @param int|null $count 拼数(纯数字)
  1453. * @return float|null
  1454. */
  1455. protected function calculateStripPriceByRow(array $row, $count)
  1456. {
  1457. $name = $row['machine_name'];
  1458. $basePrice = (float)$row['price1'];
  1459. if (strpos($name, '1-4拼(特种纸') !== false) {
  1460. if ($count === null) {
  1461. $this->error('请传入拼数(纯数字)');
  1462. }
  1463. if ($count <= 4) {
  1464. return $basePrice;
  1465. }
  1466. return floatval(number_format($basePrice + ($count - 4) * 0.001, 4, '.', ''));
  1467. }
  1468. if (strpos($name, '1-4拼(小盒二次拆片') !== false) {
  1469. if ($count === null) {
  1470. $this->error('请传入拼数(纯数字)');
  1471. }
  1472. if ($count === 8) {
  1473. return 0.01;
  1474. }
  1475. if ($count === 10) {
  1476. return 0.012;
  1477. }
  1478. return $basePrice;
  1479. }
  1480. if (strpos($name, '5-6拼(小盒二次拆片') !== false) {
  1481. return $basePrice;
  1482. }
  1483. if (strpos($name, '6拼及以上') !== false) {
  1484. return $basePrice;
  1485. }
  1486. if (preg_match('/^(\d+)拼/u', $name, $matches)) {
  1487. if ($count === null) {
  1488. $this->error('请传入拼数(纯数字)');
  1489. }
  1490. }
  1491. return $basePrice;
  1492. }
  1493. /**
  1494. * 报工数据删除
  1495. * @return void
  1496. * @throws \Exception
  1497. * @throws \think\db\exception\DataNotFoundException
  1498. * @throws \think\db\exception\ModelNotFoundException
  1499. * @throws \think\exception\DbException
  1500. * @throws \think\exception\PDOException
  1501. */
  1502. public function deleteGluingReportData()
  1503. {
  1504. if ($this->request->isPost() === false){
  1505. $this->error('请求错误');
  1506. }
  1507. $params = $this->request->param();
  1508. if (!isset($params['id']) || empty($params['id'])){
  1509. $this->error('参数错误');
  1510. }
  1511. $ids = explode(',', $params['id']);
  1512. $roleIds = \db('设备_糊盒报工资料')
  1513. ->where('Uid', 'in', $ids)
  1514. ->column('role');
  1515. $roleIds = array_filter(array_unique($roleIds));
  1516. db()->startTrans();
  1517. try {
  1518. $res = \db('设备_糊盒报工资料')->where('Uid', 'in', $ids)->delete();
  1519. if ($res === false) {
  1520. throw new \Exception('删除报工数据失败');
  1521. }
  1522. if (!empty($roleIds)) {
  1523. $classRes = \db('糊盒报工班组')->where('id', 'in', $roleIds)->delete();
  1524. if ($classRes === false) {
  1525. throw new \Exception('删除班组数据失败');
  1526. }
  1527. }
  1528. db()->commit();
  1529. } catch (\Exception $e) {
  1530. db()->rollback();
  1531. $this->error($e->getMessage());
  1532. }
  1533. $this->success('删除成功');
  1534. }
  1535. }