Procuremenarchive.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. <?php
  2. namespace app\admin\controller;
  3. use app\common\controller\Backend;
  4. use app\common\library\ProcuremenStatus;
  5. use app\common\library\ProcuremenTime;
  6. use think\Db;
  7. /**
  8. * 协助采购 — 历史存证档案查询(已完结工序 + 操作记录详情)
  9. *
  10. * @icon fa fa-archive
  11. */
  12. class Procuremenarchive extends Backend
  13. {
  14. protected $searchFields = 'CCYDH,CYJMC,CGYMC';
  15. public function _initialize()
  16. {
  17. parent::_initialize();
  18. $this->assignconfig('procuremenAuth', [
  19. 'details' => $this->auth->check('procuremen/details'),
  20. 'archiveabandon' => $this->auth->check('procuremen/archiveabandon'),
  21. ]);
  22. }
  23. /** purchase_order.status 为已完结(兼容 varchar / 数字 / 首尾空格) */
  24. protected function applyPurchaseOrderCompletedWhere($query): void
  25. {
  26. $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status'));
  27. }
  28. public function index()
  29. {
  30. $this->relationSearch = false;
  31. $this->request->filter(['strip_tags', 'trim']);
  32. if ($this->request->isAjax()) {
  33. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  34. $limit = max(10, min(500, (int)$limit));
  35. $offset = max(0, (int)$offset);
  36. $applyFilters = function ($query) use ($where) {
  37. $this->applyPurchaseOrderCompletedWhere($query);
  38. if (!empty($where)) {
  39. $query->where($where);
  40. }
  41. };
  42. $sortField = preg_match('/^[a-zA-Z0-9_]+$/', (string)$sort) ? $sort : 'id';
  43. $orderDir = strtoupper((string)$order) === 'ASC' ? 'ASC' : 'DESC';
  44. $listQuery = Db::table('purchase_order');
  45. $applyFilters($listQuery);
  46. $rows = $listQuery
  47. ->field('id,scydgy_id,CCYDH,CYJMC,CGYMC,createtime,dStamp,pick_time')
  48. ->order($sortField, $orderDir)
  49. ->select();
  50. if (!is_array($rows)) {
  51. $rows = [];
  52. }
  53. $sidList = [];
  54. foreach ($rows as $r) {
  55. if (!is_array($r)) {
  56. continue;
  57. }
  58. $sid = (int)($r['scydgy_id'] ?? 0);
  59. if ($sid !== 0) {
  60. $sidList[$sid] = true;
  61. }
  62. }
  63. $completeTsMap = ProcuremenTime::loadOperLogTimestampMap(
  64. array_keys($sidList),
  65. ['purchase_confirm', 'mark_complete']
  66. );
  67. $out = [];
  68. foreach ($rows as $r) {
  69. if (!is_array($r)) {
  70. continue;
  71. }
  72. $sid = (int)($r['scydgy_id'] ?? 0);
  73. $done = ProcuremenTime::resolveCompletedDone($r, $completeTsMap);
  74. $out[] = [
  75. 'id' => (int)($r['id'] ?? 0),
  76. 'scydgy_id' => $sid,
  77. 'CCYDH' => trim((string)($r['CCYDH'] ?? '')),
  78. 'CYJMC' => trim((string)($r['CYJMC'] ?? '')),
  79. 'CGYMC' => trim((string)($r['CGYMC'] ?? '')),
  80. 'createtime' => $done['ts'],
  81. 'createtime_text' => $done['text'],
  82. ];
  83. }
  84. $merged = $this->collapseArchiveRowsByOrder($out);
  85. $nMerged = count($merged);
  86. if ($nMerged > 1 && $sortField === 'id') {
  87. usort($merged, function ($a, $b) use ($orderDir) {
  88. $cmp = ((int)($a['id'] ?? 0)) <=> ((int)($b['id'] ?? 0));
  89. if ($cmp === 0) {
  90. return strcmp((string)($a['CCYDH'] ?? ''), (string)($b['CCYDH'] ?? ''));
  91. }
  92. return $orderDir === 'ASC' ? $cmp : -$cmp;
  93. });
  94. } elseif ($nMerged > 1 && $sortField === 'createtime') {
  95. usort($merged, function ($a, $b) use ($orderDir) {
  96. $ta = (int)($a['createtime'] ?? 0);
  97. $tb = (int)($b['createtime'] ?? 0);
  98. if ($ta === $tb) {
  99. return ((int)($b['id'] ?? 0)) <=> ((int)($a['id'] ?? 0));
  100. }
  101. return $orderDir === 'ASC' ? ($ta <=> $tb) : ($tb <=> $ta);
  102. });
  103. }
  104. $pageRows = array_slice($merged, $offset, $limit);
  105. return json(['total' => $nMerged, 'rows' => $pageRows]);
  106. }
  107. return $this->view->fetch();
  108. }
  109. /**
  110. * 历史存证:同一订单号 CCYDH 合并为一行(与审批/确认列表一致)
  111. *
  112. * @param array<int, array<string, mixed>> $rows
  113. * @return array<int, array<string, mixed>>
  114. */
  115. protected function collapseArchiveRowsByOrder(array $rows): array
  116. {
  117. if ($rows === []) {
  118. return [];
  119. }
  120. $groups = [];
  121. foreach ($rows as $row) {
  122. if (!is_array($row)) {
  123. continue;
  124. }
  125. $dh = trim((string)($row['CCYDH'] ?? ''));
  126. $key = $dh !== '' ? $dh : ('_id_' . (int)($row['id'] ?? 0));
  127. if (!isset($groups[$key])) {
  128. $groups[$key] = [];
  129. }
  130. $groups[$key][] = $row;
  131. }
  132. $out = [];
  133. foreach ($groups as $groupRows) {
  134. if ($groupRows === []) {
  135. continue;
  136. }
  137. usort($groupRows, function ($a, $b) {
  138. return ((int)($a['id'] ?? 0)) <=> ((int)($b['id'] ?? 0));
  139. });
  140. $head = $groupRows[0];
  141. $gymcList = [];
  142. foreach ($groupRows as $r) {
  143. $g = trim((string)($r['CGYMC'] ?? ''));
  144. if ($g !== '' && !in_array($g, $gymcList, true)) {
  145. $gymcList[] = $g;
  146. }
  147. }
  148. $merged = $head;
  149. if (count($groupRows) > 1) {
  150. $merged['CGYMC'] = implode('、', $gymcList);
  151. }
  152. $merged['process_count'] = count($groupRows);
  153. $latestTs = 0;
  154. $latestText = '';
  155. foreach ($groupRows as $r) {
  156. $ts = (int)($r['createtime'] ?? 0);
  157. if ($ts <= 0 && !empty($r['createtime_text'])) {
  158. $ts = (int)strtotime((string)$r['createtime_text']);
  159. }
  160. if ($ts > $latestTs) {
  161. $latestTs = $ts;
  162. $latestText = trim((string)($r['createtime_text'] ?? ''));
  163. }
  164. }
  165. if ($latestTs > 0) {
  166. $merged['createtime'] = $latestTs;
  167. if ($latestText === '') {
  168. $latestText = date('Y-m-d H:i:s', $latestTs);
  169. }
  170. $merged['createtime_text'] = ProcuremenTime::formatDisplayDateTime($latestText);
  171. }
  172. $maxId = (int)($head['id'] ?? 0);
  173. foreach ($groupRows as $r) {
  174. $maxId = max($maxId, (int)($r['id'] ?? 0));
  175. }
  176. $merged['id'] = $maxId;
  177. $out[] = $merged;
  178. }
  179. return $out;
  180. }
  181. }