GluingSalary.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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 GluingSalary extends Api
  10. {
  11. protected $noNeedLogin = ['*'];
  12. protected $noNeedRight = ['*'];
  13. /**
  14. * 左侧菜单
  15. * @return void
  16. * @throws \think\db\exception\DataNotFoundException
  17. * @throws \think\db\exception\ModelNotFoundException
  18. * @throws \think\exception\DbException
  19. */
  20. public function getTab()
  21. {
  22. if(!$this->request->isGet()){
  23. $this->error('请求方式错误');
  24. }
  25. $res=db('糊盒工资汇总')
  26. ->field('DATE_FORMAT(`sczl_rq`, "%Y%m") as sys_ny,bh')
  27. ->group('DATE_FORMAT(`sczl_rq`, "%Y%m"),bh')
  28. ->whereTime('sczl_rq', '>=', strtotime('-14 months'))
  29. ->where('bh','<>','000000')
  30. ->order('sczl_rq desc')
  31. ->select();
  32. foreach($res as $v){
  33. $arr[$v['sys_ny'].'('][]=$v['bh'];
  34. }
  35. $rs = db('人事_基本资料')->column('员工编号,所在部门');
  36. foreach($arr as $k=>$v){
  37. foreach($v as $value){
  38. if(array_key_exists($value,$rs)){
  39. $data[$k.count($v).'人)'][rtrim($rs[$value])][]=rtrim($rs[$value]);
  40. } }
  41. $j=0;
  42. foreach($data[$k.count($v).'人)'] as $keys=>$values){
  43. $data[$k.count($v).'人)']['bm'][$j]=$keys;
  44. $data[$k.count($v).'人)'][$keys]=count($values);
  45. $j++;
  46. }
  47. usort($data[$k.count($v).'人)']['bm'], function($a, $b) {
  48. $order = array(
  49. '胶印车间',
  50. '凹印车间',
  51. '丝印车间',
  52. '模切车间',
  53. '检验车间',
  54. '精品试验车间',
  55. '品保部',
  56. '人力资源部',
  57. '生产部',
  58. '营销部',
  59. '数字化车间',
  60. '精品车间'
  61. );
  62. $a_index = array_search($a, $order);
  63. $b_index = array_search($b, $order);
  64. return $a_index - $b_index;
  65. });
  66. foreach($data[$k.count($v).'人)']['bm'] as &$va){
  67. $va=$va.'('.$data[$k.count($v).'人)'][$va].'人)';
  68. }
  69. $data[$k.count($v).'人)']=$data[$k.count($v).'人)']['bm'];
  70. }
  71. $i=0;
  72. foreach($data as $k=>$v){
  73. $datas[$i]['label']=$k;
  74. $gdbh=substr($k,0,strpos($k,'('));
  75. foreach($v as $key=>$value){
  76. $datas[$i]['children'][$key]['label']=$value;
  77. $datas[$i]['children'][$key]['gdbh']=$gdbh;
  78. }
  79. $i++;
  80. }
  81. $this->success('成功',$datas);
  82. }
  83. /**
  84. * 上方列表
  85. * @return void
  86. * @throws \think\db\exception\DataNotFoundException
  87. * @throws \think\db\exception\ModelNotFoundException
  88. * @throws \think\exception\DbException
  89. */
  90. // public function getList()
  91. // {
  92. //
  93. // if(!$this->request->isGet()){
  94. // $this->error('请求方式错误');
  95. // }
  96. // $req = $this->request->param();
  97. // if (isset($req['search'])){
  98. // $where = [
  99. // 'sczl_rq' => ['like',$req['date'].'%'],
  100. // 'bh|name' => ['like',$req['search'].'%'],
  101. // ];
  102. // $res = db('糊盒工资汇总')
  103. // ->where($where)
  104. // ->group('bh, sczl_rq')
  105. // ->field('bh as 员工编号, DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期, name as 姓名, sum(salary) as 计件工资')
  106. // ->select();
  107. // }else{
  108. // $where = [
  109. // 'a.sczl_rq' => ['like',$req['date'].'%'],
  110. // 'b.所在部门' => ['like', $req['department'] . '%']
  111. // ];
  112. // $res = db('糊盒工资汇总')
  113. // ->alias('a')
  114. // ->join('人事_基本资料 b', 'b.员工编号 = a.bh')
  115. // ->where($where)
  116. // ->group('a.bh, a.sczl_rq')
  117. // ->field('a.bh as 员工编号, DATE_FORMAT(a.sczl_rq, "%Y.%m.%d") as 日期, a.name as 姓名, sum(a.salary) as 计件工资')
  118. // ->select();
  119. // }
  120. //
  121. // $processedData = [];
  122. //
  123. // foreach ($res as $item) {
  124. // // 用「员工编号」作为唯一分组键(编号唯一,比编号+姓名更简洁)
  125. // $empNo = $item['员工编号'];
  126. //
  127. // // 转换工资为浮点型(避免字符串拼接导致计算错误)
  128. // $salary = (float)$item['计件工资'];
  129. //
  130. // if (!isset($processedData[$empNo])) {
  131. // // 初始化该员工的分组数据
  132. // $processedData[$empNo] = [
  133. // '员工编号' => $empNo,
  134. // '姓名' => $item['姓名'],
  135. // '月工资总和' => 0.00, // 初始化为浮点型,保证精度
  136. // '每日明细' => [] // 存储按时间排序的每日工资
  137. // ];
  138. // }
  139. //
  140. // // 累加月工资总和
  141. // $processedData[$empNo]['月工资总和'] += $salary;
  142. // $processedData[$empNo]['月工资总和'] = number_format($processedData[$empNo]['月工资总和'],2);
  143. // // 将当前日期的工资存入明细(保留原始字段)
  144. // $processedData[$empNo]['每日明细'][] = [
  145. // '日期' => $item['日期'],
  146. // '计件工资' => $item['计件工资'] // 保留原始字符串格式,避免精度丢失
  147. // ];
  148. // }
  149. //
  150. // // 对每个员工的「每日明细」按日期升序排序
  151. // foreach ($processedData as &$empData) {
  152. // usort($empData['每日明细'], function($a, $b) {
  153. // // 将日期字符串转换为时间戳进行比较
  154. // $timeA = strtotime(str_replace('.', '-', $a['日期']));
  155. // $timeB = strtotime(str_replace('.', '-', $b['日期']));
  156. // return $timeA - $timeB; // 升序排序(从小到大)
  157. // });
  158. // }
  159. // unset($empData); // 释放引用,避免后续误操作
  160. //
  161. // // 转换为索引数组(可选,便于前端遍历)
  162. // $finalData = array_values($processedData);
  163. //
  164. // $this->success('成功',$finalData);
  165. // }
  166. public function getList()
  167. {
  168. // 1. 请求验证
  169. if (!$this->request->isGet()) {
  170. $this->error('请求方式错误');
  171. }
  172. $req = $this->request->param();
  173. // 2. 获取查询条件
  174. $where = $this->buildWhereConditions($req);
  175. // 3. 执行查询
  176. $res = $this->executeQuery($req, $where);
  177. if (empty($res)) {
  178. $this->success('成功', []);
  179. }
  180. // 4. 处理数据
  181. $finalData = $this->processResultData($res);
  182. $this->success('成功', $finalData);
  183. }
  184. /**
  185. * 构建查询条件
  186. */
  187. private function buildWhereConditions(array $req): array
  188. {
  189. $where = [];
  190. // 确保日期条件始终存在
  191. if (!empty($req['date'])) {
  192. $where['sczl_rq'] = ['like', $req['date'] . '%'];
  193. }
  194. // 如果有搜索条件,添加员工编号/姓名的模糊查询
  195. if (!empty($req['search'])) {
  196. $where['bh|name'] = ['like', $req['search'] . '%'];
  197. }
  198. return $where;
  199. }
  200. /**
  201. * 执行数据库查询
  202. */
  203. private function executeQuery(array $req, array $where)
  204. {
  205. $query = db('糊盒工资汇总');
  206. // 判断是否需要联表查询
  207. if (empty($req['search']) && !empty($req['department'])) {
  208. return $this->executeJoinedQuery($query, $req, $where);
  209. }
  210. return $this->executeSimpleQuery($query, $where);
  211. }
  212. /**
  213. * 执行简单查询(不需要联表)
  214. */
  215. private function executeSimpleQuery($query, array $where)
  216. {
  217. return $query
  218. ->where($where)
  219. ->group('bh, sczl_rq')
  220. ->field([
  221. 'bh as 员工编号',
  222. 'DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期',
  223. 'name as 姓名',
  224. 'sum(salary) as 计件工资'
  225. ])
  226. ->select();
  227. }
  228. /**
  229. * 执行联表查询(需要部门筛选)
  230. */
  231. private function executeJoinedQuery($query, array $req, array $where)
  232. {
  233. // 移除原始的sczl_rq条件,改用别名
  234. if (isset($where['sczl_rq'])) {
  235. unset($where['sczl_rq']);
  236. $where['a.sczl_rq'] = ['like', $req['date'] . '%'];
  237. }
  238. // 添加部门条件
  239. $where['b.所在部门'] = ['like', $req['department'] . '%'];
  240. return $query
  241. ->alias('a')
  242. ->join('人事_基本资料 b', 'b.员工编号 = a.bh')
  243. ->where($where)
  244. ->group('a.bh, a.sczl_rq')
  245. ->field([
  246. 'a.bh as 员工编号',
  247. 'DATE_FORMAT(a.sczl_rq, "%Y.%m.%d") as 日期',
  248. 'a.name as 姓名',
  249. 'sum(a.salary) as 计件工资'
  250. ])
  251. ->select();
  252. }
  253. /**
  254. * 处理查询结果数据
  255. */
  256. private function processResultData(array $results): array
  257. {
  258. $processedData = [];
  259. foreach ($results as $item) {
  260. $empNo = $item['员工编号'];
  261. $salary = (float)$item['计件工资'];
  262. if (!isset($processedData[$empNo])) {
  263. $processedData[$empNo] = $this->initEmployeeData($item);
  264. }
  265. $processedData[$empNo] = $this->updateEmployeeData(
  266. $processedData[$empNo],
  267. $item,
  268. $salary
  269. );
  270. }
  271. // 对每个员工的数据进行排序并格式化最终数据
  272. $processedData = $this->formatFinalData($processedData);
  273. return array_values($processedData);
  274. }
  275. /**
  276. * 初始化员工数据结构
  277. */
  278. private function initEmployeeData(array $item): array
  279. {
  280. return [
  281. '员工编号' => $item['员工编号'],
  282. '姓名' => $item['姓名'],
  283. '月工资总和' => 0.00,
  284. '每日明细' => []
  285. ];
  286. }
  287. /**
  288. * 更新员工数据
  289. */
  290. private function updateEmployeeData(array $empData, array $item, float $salary): array
  291. {
  292. // 累加工资总和
  293. $empData['月工资总和'] += $salary;
  294. // 添加每日明细
  295. $empData['每日明细'][] = [
  296. '日期' => $item['日期'],
  297. '计件工资' => $item['计件工资']
  298. ];
  299. return $empData;
  300. }
  301. /**
  302. * 对每日明细按日期排序并格式化最终数据
  303. */
  304. private function formatFinalData(array $processedData): array
  305. {
  306. foreach ($processedData as &$empData) {
  307. // 1. 对每日明细排序
  308. $empData['每日明细'] = $this->sortDailyDetails($empData['每日明细']);
  309. // 2. 强制格式化月工资总和为两位小数
  310. $empData['月工资总和'] = number_format($empData['月工资总和'], 2, '.', '');
  311. }
  312. unset($empData);
  313. return $processedData;
  314. }
  315. /**
  316. * 对每日明细按日期排序
  317. */
  318. private function sortDailyDetails(array $dailyDetails): array
  319. {
  320. usort($dailyDetails, function($a, $b) {
  321. // 使用更简单的日期转换方式
  322. $timeA = strtotime(str_replace('.', '-', $a['日期']));
  323. $timeB = strtotime(str_replace('.', '-', $b['日期']));
  324. return $timeA <=> $timeB;
  325. });
  326. return $dailyDetails;
  327. }
  328. /**
  329. *下方详情
  330. * @return void
  331. * @throws \think\db\exception\DataNotFoundException
  332. * @throws \think\db\exception\ModelNotFoundException
  333. * @throws \think\exception\DbException
  334. */
  335. public function getDetail()
  336. {
  337. if($this->request->isGet() === false){
  338. $this->error('请求错误');
  339. }
  340. $req = $this->request->param();
  341. if (!isset($req['date'])){
  342. $this->error('参数错误');
  343. }
  344. $list = \db('糊盒工资汇总')
  345. ->field('sczl_gdbh,sczl_gxmc,DATE_FORMAT(sczl_rq, "%Y.%m.%d") as 日期,sczl_jtbh,cpdh,cpmc,保养工时,装版工时,
  346. 异常工时,设备运行工时,rate as 分配比例,sczl_cl,price')
  347. ->where([
  348. 'sczl_rq' => ['like',$req['date'].'%'],
  349. 'bh' => $req['code']
  350. ])
  351. ->order('sczl_rq')
  352. ->select();
  353. if(empty($list)){
  354. $this->error('失败');
  355. }else{
  356. $this->success('成功',$list);
  357. }
  358. }
  359. }