| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- <?php
- namespace app\admin\controller;
- use app\common\controller\Backend;
- use app\common\library\ProcuremenSupplierScore;
- use PhpOffice\PhpSpreadsheet\Spreadsheet;
- use PhpOffice\PhpSpreadsheet\Style\Alignment;
- use PhpOffice\PhpSpreadsheet\Style\Border;
- use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
- use think\Db;
- /**
- * 供应商服务评分表(开标后按订单落库)
- *
- * @icon fa fa-trophy
- */
- class Supplierservicescore extends Backend
- {
- /** @var \app\admin\model\Supplierservicescore */
- protected $model = null;
- protected $searchFields = 'ccydh,company_name';
- /** 有列表权限即可导出(避免仅缺子权限导致按钮可见却下载失败) */
- protected $noNeedRight = ['export'];
- public function _initialize()
- {
- parent::_initialize();
- ProcuremenSupplierScore::ensureSchema();
- $this->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;
- }
- }
|