public function scoreImg($scope, $course) { $data = $this->scoreAll($scope, $course); //宽度 $imgWidth = $headBoxWidth = $dataBoxWidth = 720; //标题高度 $headBoxHeight = 80; //数据行高度 $dataBoxHeight = 60; //整体高度 $imgHeight = $headBoxHeight + (count($data) + 2) * $dataBoxHeight; //创建图像 $im = imagecreate($imgWidth, $imgHeight); //图片字体设置 $font = Config::BASE_PATH . Config::FONT_PATH; //定义颜色 $headBoxColor = ImageColorAllocate($im, 217, 237, 247); $headFontColor = ImageColorAllocate($im, 91, 192, 222); $titleBoxColor = ImageColorAllocate($im, 223, 240, 216); $oddBoxColor = ImageColorAllocate($im, 245, 245, 245); $evenBoxColor = ImageColorAllocate($im, 255, 255, 255); $failBoxColor = ImageColorAllocate($im, 242, 222, 222); $markBoxColor = ImageColorAllocate($im, 217, 237, 247); $dataFontColor = ImageColorAllocate($im, 51, 51, 51); //headBox imagefilledrectangle($im, 0, 0, $headBoxWidth, $headBoxHeight, $headBoxColor); //head $head = ($scope == 'class' ? $this->class : $this->major) . ' '; if (strlen($course) > 15 * 3) { $head .= substr($course, 0, 14 * 3) . '...'; } else { $head .= $course; } $headFontSize = 20; $headSize = ImageTTFBBox($headFontSize, 0, $font, $head); $headWidth = $headSize[2] - $headSize[0]; $headHeight = $headSize[1] - $headSize[5]; $headOffsetX = -$headSize[0]; $headOffsetY = -$headSize[5]; $headX = (int) ($headBoxWidth - $headWidth) / 2 + $headOffsetX; $headY = (int) ($headBoxHeight - $headHeight) / 2 + $headOffsetY; ImageTTFText($im, $headFontSize, 0, $headX, $headY, $headFontColor, $font, $head); //成绩排序 usort($data, function ($a, $b) { return \Hnust\scoreCompare($a['score'], $b['score']); }); //数据填充 for ($i = -1; $i <= count($data); $i++) { //单双行背景 if ($i % 2) { $dataBoxColor = $oddBoxColor; } else { $dataBoxColor = $evenBoxColor; } if ($i == -1) { $dataBoxColor = $titleBoxColor; $row = array('学号', '姓名', '分数'); } else { if ($i == count($data)) { $dataBoxColor = $markBoxColor; $row = array('注:带*的为补考;By:Tick网络工作室'); } else { $score = $data[$i]['score']; //不及格红色标记 if (is_numeric($score) && $score < 60 || $score == '不及格' || empty($score)) { $dataBoxColor = $failBoxColor; } //补考加×号 if ($data[$i]['resit']) { $score .= '*'; } $row = array($data[$i]['sid'], $data[$i]['name'], $score); } } //填充一行背景色 $dataBoxOffsetHeight = $headBoxHeight + ($i + 1) * $dataBoxHeight; imagefilledrectangle($im, 0, $dataBoxOffsetHeight, $dataBoxWidth, $dataBoxOffsetHeight + $dataBoxHeight, $dataBoxColor); //填入一行数据 for ($j = 0; $j < count($row); $j++) { $dataFontSize = 16; $dataSize = ImageTTFBBox($dataFontSize, 0, $font, $row[$j]); $dataWidth = $dataSize[2] - $dataSize[0]; $dataHeight = $dataSize[1] - $dataSize[5]; $dataOffsetX = -$dataSize[0]; $dataOffsetY = $headBoxHeight + ($i + 1) * $dataBoxHeight - $dataSize[5]; $dataX = (int) ($dataBoxWidth / count($row) - $dataWidth) / 2 + $dataBoxWidth / count($row) * $j + $dataOffsetX; $dataY = (int) ($dataBoxHeight - $dataHeight) / 2 + $dataOffsetY; ImageTTFText($im, $dataFontSize, 0, $dataX, $dataY, $dataFontColor, $font, $row[$j]); } } //输出下载 $fileName = ($scope == 'class' ? $this->class : $this->major) . "_{$course}.png"; header('Content-type: image/png'); header("Content-Disposition: attachment; filename={$fileName}"); ImagePng($im); ImageDestroy($im); exit; }
public function getRank($term, $scope, $by) { //获取学生信息 $sql = 'SELECT `class`, `major`, `grade`, `school` FROM `student` WHERE `sid` = ? LIMIT 1'; $result = Mysql::execute($sql, array($this->sid)); $this->class = $result[0]['class']; $this->major = $result[0]['major']; $this->grade = $result[0]['grade']; $this->school = $result[0]['school']; //sql语句及sql数组 if ('class' === $scope) { $sql = "SELECT `a`.`sid`, `a`.`name`, `a`.`class`, `a`.`major`,\n IF(`b`.`score` IS NULL, '[]', `b`.`score`) `score`\n FROM `student` `a`\n LEFT JOIN `score` `b` ON `a`.`sid` = `b`.`sid`\n WHERE `a`.`class` = ?"; $students = Mysql::execute($sql, array($this->class)); $this->title = $this->class . $term . ($by == 'term' ? '学期排名' : '学年排名'); $this->rankName = $this->class; } else { $sql = "SELECT `a`.`sid`, `a`.`name`, `a`.`class`, `a`.`major`,\n IF(`b`.`score` IS NULL, '[]', `b`.`score`) `score`\n FROM `student` `a`\n LEFT JOIN `score` `b` ON `a`.`sid` = `b`.`sid`\n WHERE `a`.`major` = ? AND `a`.`grade` = ? AND `a`.`school` = ?"; $students = Mysql::execute($sql, array($this->major, $this->grade, $this->school)); $this->title = $this->major . $term . ($by == 'term' ? '学期排名' : '学年排名'); $this->rankName = $this->major; } //选择要排名的学期及成绩 $this->terms = array(); $rankCourse = array(); for ($i = 0; $i < count($students); $i++) { $score = @json_decode($students[$i]['score'], true); $rankScore = array(); //统计学期和获取待排名成绩 foreach ($score as $scoreTerm => $termScore) { //区分学期排名与学年排名 $tempTerm = $by != 'term' ? substr($scoreTerm, 0, 9) : $scoreTerm; //统计学期 for ($j = 0; $j < count($this->terms); $j++) { if ($this->terms[$j] == $tempTerm) { break; } } if ($j == count($this->terms)) { $this->terms[$j] = $tempTerm; } //去除补考 for ($j = 0; $j < count($score[$scoreTerm]); $j++) { if ($score[$scoreTerm][$j]['resit'] == true) { array_splice($score[$scoreTerm], $j--, 1); } } //获取待排名成绩 if ($term == $tempTerm) { $rankScore = array_merge($rankScore, $score[$scoreTerm]); } } //遍历待排名所有成绩 for ($j = 0; $j < count($rankScore); $j++) { //统计科目 for ($k = 0; $k < count($rankCourse); $k++) { if ($rankScore[$j]['course'] == $rankCourse[$k]['course']) { break; } } if ($k == count($rankCourse) && !empty($rankScore[$j]['credit'])) { $rankCourse[$k] = array('course' => $rankScore[$j]['course'], 'mode' => $rankScore[$j]['mode'], 'credit' => $rankScore[$j]['credit'], 'count' => 1); } elseif ($k != count($rankCourse)) { $rankCourse[$k]['count']++; } //遍历其他成绩 foreach ($score as $termScore) { for ($k = 0; $k < count($termScore); $k++) { //取科目最高分 if ($rankScore[$j]['course'] == $termScore[$k]['course'] && \Hnust\scoreCompare($rankScore[$j]['mark'], $termScore[$k]['mark'])) { $rankScore[$j]['mark'] = $termScore[$k]['mark']; } } } } $students[$i]['rankScore'] = $rankScore; } //删除选修等科目 for ($i = 0; $i < count($rankCourse); $i++) { if ($rankCourse[$i]['count'] < count($students) * 0.8) { array_splice($rankCourse, $i--, 1); } } //课程全部存入info数组 $this->courses = array(); for ($i = 0; $i < count($rankCourse); $i++) { $this->courses[$i] = $rankCourse[$i]['course']; } //计算 for ($i = 0; $i < count($students); $i++) { $courseMark = array(); $rankScore = $students[$i]['rankScore']; $countFail = $countMark = $countCredit = $totalCredit = $countGpa = $countPoint = 0; for ($j = 0; $j < count($rankCourse); $j++) { //获取单科分数 $courseMark[$j] = 0; for ($k = 0; $k < count($rankScore); $k++) { if ($rankCourse[$j]['course'] == $rankScore[$k]['course'] && \Hnust\scoreCompare($courseMark[$j], $rankScore[$k]['mark'])) { $courseMark[$j] = $rankScore[$k]['mark']; } } //将等级制转换为分数 $tempMark = (double) str_replace(array('优', '良', '中', '及格', '不及格'), array(95.02, 84.02, 74.02, 60.02, 0), $courseMark[$j]); //分数转化为对应绩点 $pointArray = array(90 => 4, 85 => 3.7, 82 => 3.3, 78 => 3.0, 75 => 2.7, 71 => 2.3, 66 => 2.0, 62 => 1.5, 60 => 1, 0 => 0); foreach ($pointArray as $mark => $point) { if ($mark <= $tempMark) { $tempPoint = $point; break; } } $countFail += $tempMark >= 60 ? 0 : 1; $countMark += $tempMark; $countCredit += $tempMark >= 60 ? $rankCourse[$j]['credit'] : 0; $totalCredit += $rankCourse[$j]['credit']; $countGpa += $tempMark * $rankCourse[$j]['credit']; $countPoint += $tempPoint * $rankCourse[$j]['credit']; } $avgMark = count($rankCourse) ? round($countMark / count($rankCourse), 2) : 0; $countMark = round($countMark, 2); $countCredit = round($countCredit, 2); $avgGpa = $totalCredit ? round($countGpa / $totalCredit, 2) : 0; $avgPoint = $totalCredit ? round($countPoint / $totalCredit, 2) : 0; $rank[] = array('name' => $students[$i]['name'], 'sid' => $students[$i]['sid'], 'course' => $courseMark, 'countFail' => $countFail, 'avgMark' => $avgMark, 'countMark' => $countMark, 'countCredit' => $countCredit, 'avgGpa' => $avgGpa, 'avgPoint' => $avgPoint); } //名次排序 usort($rank, function ($a, $b) { $re = $a['avgGpa'] == $b['avgGpa'] ? $a['sid'] < $b['sid'] : $a['avgGpa'] > $b['avgGpa']; return $re ? -1 : 1; }); for ($i = 0; $i < count($rank); $i++) { $rank[$i]['rank'] = $i + 1; } return $rank; }