model = new \app\admin\model\Supplierservicescore; } public function index() { $this->request->filter(['strip_tags', 'trim']); if ($this->request->isAjax()) { list($where, $sort, $order, $offset, $limit) = $this->buildparams(); $sort = trim((string)$sort); $order = strtolower(trim((string)$order)) === 'asc' ? 'asc' : 'desc'; // 同一订单内总分从高到低;默认按订单号分组 if ($sort === '' || $sort === 'ccydh' || $sort === 'id') { $query = $this->model->where($where)->order('ccydh', $order)->order('score', 'desc'); } elseif ($sort === 'score' || $sort === 'score_text' || $sort === 'rank_no') { $query = $this->model->where($where)->order('score', $order)->order('ccydh', 'desc'); } else { $query = $this->model->where($where)->order($sort, $order)->order('ccydh', 'desc')->order('score', 'desc'); } $list = $query->paginate($limit); $ruleMap = []; $defaultRule = ProcuremenSupplierScore::getDefaultRule(); $rows = []; foreach ($list as $row) { $arr = $row->toArray(); $arr['score_text'] = ProcuremenSupplierScore::formatScore($arr['score'] ?? 0); $qw = $arr['quality_weight'] ?? null; $pw = $arr['price_weight'] ?? null; if ($qw === null || $qw === '' || $pw === null || $pw === '') { $rid = (int)($arr['rule_id'] ?? 0); if ($rid > 0 && !isset($ruleMap[$rid])) { try { $rr = Db::table('supplier_score_rule')->where('id', $rid)->find(); $ruleMap[$rid] = is_array($rr) ? $rr : null; } catch (\Throwable $e) { $ruleMap[$rid] = null; } } $rule = ($rid > 0 && is_array($ruleMap[$rid] ?? null)) ? $ruleMap[$rid] : $defaultRule; if ($qw === null || $qw === '') { $qw = $rule['quality_weight'] ?? 50; } if ($pw === null || $pw === '') { $pw = $rule['price_weight'] ?? 50; } } $arr['quality_weight'] = $qw; $arr['price_weight'] = $pw; $arr['quality_weight_text'] = rtrim(rtrim(sprintf('%.2F', (float)$qw), '0'), '.') . '%'; $arr['price_weight_text'] = rtrim(rtrim(sprintf('%.2F', (float)$pw), '0'), '.') . '%'; $rows[] = $arr; } return json(['total' => $list->total(), 'rows' => $rows]); } return $this->view->fetch(); } /** * 导出供应商评审表:按月份汇总供应商,总分从高到低 * 列:序号、供应商名称、总分(对应原模板「评审等级」位置) */ public function export() { $ym = trim((string)$this->request->param('ym', '')); if (!preg_match('/^(\d{4})-(\d{2})$/', $ym, $m)) { $this->error('请选择查询月份'); } $year = (int)$m[1]; $month = (int)$m[2]; if ($month < 1 || $month > 12) { $this->error('查询月份无效'); } ProcuremenSupplierScore::ensureSchema(); try { $rows = Db::table('supplier_service_score') ->where('ym', $ym) ->field('company_name, score') ->select(); } catch (\Throwable $e) { $rows = []; } if (!is_array($rows)) { $rows = []; } // 同一供应商当月多条:取平均总分 $byCompany = []; foreach ($rows as $r) { if (!is_array($r)) { continue; } $name = trim((string)($r['company_name'] ?? '')); if ($name === '') { continue; } if (!isset($byCompany[$name])) { $byCompany[$name] = ['sum' => 0.0, 'cnt' => 0]; } $byCompany[$name]['sum'] += (float)($r['score'] ?? 0); $byCompany[$name]['cnt']++; } $list = []; foreach ($byCompany as $name => $agg) { $avg = $agg['cnt'] > 0 ? round($agg['sum'] / $agg['cnt'], 2) : 0.0; $list[] = [ 'company_name' => $name, 'score' => $avg, 'score_text' => ProcuremenSupplierScore::formatScore($avg), ]; } usort($list, function ($a, $b) { $sa = (float)($a['score'] ?? 0); $sb = (float)($b['score'] ?? 0); if ($sa !== $sb) { return $sb <=> $sa; } return strcmp((string)($a['company_name'] ?? ''), (string)($b['company_name'] ?? '')); }); $title = $year . '年' . $month . '月外协加工供应商评审表'; $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setTitle('供应商评审表'); // 样式对齐原纸质/Excel 评审表:大标题、居中、黑框、行高加高 $fontName = '宋体'; $borderStyle = [ 'borders' => [ 'allBorders' => [ 'borderStyle' => Border::BORDER_THIN, 'color' => ['rgb' => '000000'], ], ], ]; $centerAlign = [ 'horizontal' => Alignment::HORIZONTAL_CENTER, 'vertical' => Alignment::VERTICAL_CENTER, 'wrapText' => true, ]; $sheet->mergeCells('A1:C1'); $sheet->setCellValue('A1', $title); $sheet->getRowDimension(1)->setRowHeight(36); $sheet->getStyle('A1')->getFont()->setName($fontName)->setBold(true)->setSize(20); $sheet->getStyle('A1')->getAlignment()->applyFromArray($centerAlign); $sheet->setCellValue('A2', '序号'); $sheet->setCellValue('B2', '供应商名称'); $sheet->setCellValue('C2', '总分'); $sheet->getRowDimension(2)->setRowHeight(26); $sheet->getStyle('A2:C2')->getFont()->setName($fontName)->setBold(true)->setSize(14); $sheet->getStyle('A2:C2')->getAlignment()->applyFromArray($centerAlign); $rowNum = 3; if ($list === []) { $sheet->mergeCells('A3:C3'); $sheet->setCellValue('A3', '(该月暂无供应商服务评分数据)'); $sheet->getRowDimension(3)->setRowHeight(26); $sheet->getStyle('A3')->getFont()->setName($fontName)->setSize(12); $sheet->getStyle('A3')->getAlignment()->applyFromArray($centerAlign); $rowNum = 4; } else { $i = 1; foreach ($list as $item) { $sheet->setCellValue('A' . $rowNum, $i); $sheet->setCellValue('B' . $rowNum, (string)($item['company_name'] ?? '')); $sheet->setCellValue('C' . $rowNum, (string)($item['score_text'] ?? '')); $sheet->getRowDimension($rowNum)->setRowHeight(24); $rowNum++; $i++; } } $lastRow = max(2, $rowNum - 1); $sheet->getStyle('A1:C' . $lastRow)->applyFromArray($borderStyle); $sheet->getStyle('A3:C' . $lastRow)->getFont()->setName($fontName)->setSize(12); $sheet->getStyle('A3:C' . $lastRow)->getAlignment()->applyFromArray($centerAlign); $sheet->getColumnDimension('A')->setWidth(12); $sheet->getColumnDimension('B')->setWidth(48); $sheet->getColumnDimension('C')->setWidth(16); $sheet->getPageSetup()->setFitToPage(true)->setFitToWidth(1)->setFitToHeight(0); $filename = $title . '.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="' . rawurlencode($filename) . '"'); header('Cache-Control: max-age=0'); $writer = new Xlsx($spreadsheet); $writer->save('php://output'); $spreadsheet->disconnectWorksheets(); unset($spreadsheet); exit; } }