assignconfig('procuremenAuth', [ 'details' => $this->auth->check('procuremen/details'), 'archiveabandon' => $this->auth->check('procuremen/archiveabandon'), ]); } /** purchase_order.status 为已完结(兼容 varchar / 数字 / 首尾空格) */ protected function applyPurchaseOrderCompletedWhere($query): void { $query->whereRaw(ProcuremenStatus::sqlPoCompleted('status')); } public function index() { $this->relationSearch = false; $this->request->filter(['strip_tags', 'trim']); if ($this->request->isAjax()) { list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $limit = max(10, min(500, (int)$limit)); $offset = max(0, (int)$offset); $applyFilters = function ($query) use ($where) { $this->applyPurchaseOrderCompletedWhere($query); if (!empty($where)) { $query->where($where); } }; $sortField = preg_match('/^[a-zA-Z0-9_]+$/', (string)$sort) ? $sort : 'id'; $orderDir = strtoupper((string)$order) === 'ASC' ? 'ASC' : 'DESC'; $listQuery = Db::table('purchase_order'); $applyFilters($listQuery); $rows = $listQuery ->field('id,scydgy_id,CCYDH,CYJMC,CGYMC,createtime,dStamp,pick_time') ->order($sortField, $orderDir) ->select(); if (!is_array($rows)) { $rows = []; } $sidList = []; foreach ($rows as $r) { if (!is_array($r)) { continue; } $sid = (int)($r['scydgy_id'] ?? 0); if ($sid !== 0) { $sidList[$sid] = true; } } $completeTsMap = ProcuremenTime::loadOperLogTimestampMap( array_keys($sidList), ['purchase_confirm', 'mark_complete'] ); $out = []; foreach ($rows as $r) { if (!is_array($r)) { continue; } $sid = (int)($r['scydgy_id'] ?? 0); $done = ProcuremenTime::resolveCompletedDone($r, $completeTsMap); $out[] = [ 'id' => (int)($r['id'] ?? 0), 'scydgy_id' => $sid, 'CCYDH' => trim((string)($r['CCYDH'] ?? '')), 'CYJMC' => trim((string)($r['CYJMC'] ?? '')), 'CGYMC' => trim((string)($r['CGYMC'] ?? '')), 'createtime' => $done['ts'], 'createtime_text' => $done['text'], ]; } $merged = $this->collapseArchiveRowsByOrder($out); $nMerged = count($merged); if ($nMerged > 1 && $sortField === 'id') { usort($merged, function ($a, $b) use ($orderDir) { $cmp = ((int)($a['id'] ?? 0)) <=> ((int)($b['id'] ?? 0)); if ($cmp === 0) { return strcmp((string)($a['CCYDH'] ?? ''), (string)($b['CCYDH'] ?? '')); } return $orderDir === 'ASC' ? $cmp : -$cmp; }); } elseif ($nMerged > 1 && $sortField === 'createtime') { usort($merged, function ($a, $b) use ($orderDir) { $ta = (int)($a['createtime'] ?? 0); $tb = (int)($b['createtime'] ?? 0); if ($ta === $tb) { return ((int)($b['id'] ?? 0)) <=> ((int)($a['id'] ?? 0)); } return $orderDir === 'ASC' ? ($ta <=> $tb) : ($tb <=> $ta); }); } $pageRows = array_slice($merged, $offset, $limit); return json(['total' => $nMerged, 'rows' => $pageRows]); } return $this->view->fetch(); } /** * 历史存证:同一订单号 CCYDH 合并为一行(与审批/确认列表一致) * * @param array> $rows * @return array> */ protected function collapseArchiveRowsByOrder(array $rows): array { if ($rows === []) { return []; } $groups = []; foreach ($rows as $row) { if (!is_array($row)) { continue; } $dh = trim((string)($row['CCYDH'] ?? '')); $key = $dh !== '' ? $dh : ('_id_' . (int)($row['id'] ?? 0)); if (!isset($groups[$key])) { $groups[$key] = []; } $groups[$key][] = $row; } $out = []; foreach ($groups as $groupRows) { if ($groupRows === []) { continue; } usort($groupRows, function ($a, $b) { return ((int)($a['id'] ?? 0)) <=> ((int)($b['id'] ?? 0)); }); $head = $groupRows[0]; $gymcList = []; foreach ($groupRows as $r) { $g = trim((string)($r['CGYMC'] ?? '')); if ($g !== '' && !in_array($g, $gymcList, true)) { $gymcList[] = $g; } } $merged = $head; if (count($groupRows) > 1) { $merged['CGYMC'] = implode('、', $gymcList); } $merged['process_count'] = count($groupRows); $latestTs = 0; $latestText = ''; foreach ($groupRows as $r) { $ts = (int)($r['createtime'] ?? 0); if ($ts <= 0 && !empty($r['createtime_text'])) { $ts = (int)strtotime((string)$r['createtime_text']); } if ($ts > $latestTs) { $latestTs = $ts; $latestText = trim((string)($r['createtime_text'] ?? '')); } } if ($latestTs > 0) { $merged['createtime'] = $latestTs; if ($latestText === '') { $latestText = date('Y-m-d H:i:s', $latestTs); } $merged['createtime_text'] = ProcuremenTime::formatDisplayDateTime($latestText); } $maxId = (int)($head['id'] ?? 0); foreach ($groupRows as $r) { $maxId = max($maxId, (int)($r['id'] ?? 0)); } $merged['id'] = $maxId; $out[] = $merged; } return $out; } }