123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <?php
- namespace App\Http\Controllers\Api\Video;
- use App\Facades\Servers\WechatMini\Mini;
- use App\Http\Controllers\Api\Api;
- use App\Models\Video\Course;
- use App\Models\Video\LearnRecord;
- use Intervention\Image\Facades\Image;
- use Intervention\Image\Gd\Font;
- class LearnReportShareImage extends Api
- {
- /**
- * 学习中报告图片 /api/learn_report_share_image/get
- * @param LearnRecord $learnRecordModel
- * @param Course $courseModel
- * @return array|string
- * @throws \App\Exceptions\Api\LoginException
- */
- public function get_share_image(LearnRecord $learnRecordModel, Course $courseModel)
- {
- // 登录信息
- $uid = $this->checkLogin();
- // 接收参数
- $courseId = request('course_id', 0);
- $fontPath = public_path() . '/fonts/msyh14.ttf'; // 指定字体文件路径
- //学习课程名称
- $courseName = $courseModel->query()->where([['id', '=', $courseId]])->value('name');
- $courseName = str_replace(' ', '', $courseName); //去除课程名称中的空格
- //获取总积分(客户)
- $totalScore = $learnRecordModel->query()->where([['course_id', '=', $courseId], ['custom_uid', '=', $uid]])->sum('get_score');
- // 尝试执行
- try {
- // 加载图片
- $image = Image::make(public_path('uploads/images/default/') . 'learn_report_share_base.png');
- $lineHeight = 30; // 行高
- $fontSize = 24;
- $maxWidth = 330;
- // 课程名称过长的时候需要截断
- $lines = $this->truncateText($courseName, $fontPath, $fontSize, $maxWidth);
- $y = 170; // 初始 y 坐标
- // 处理数据
- foreach ($lines as $line) {
- $image->text($line, 30, $y, function ($font) use ($fontPath, $fontSize) {
- $font->file($fontPath);
- $font->size($fontSize);
- $font->color('#2B3D7c');
- $font->align('left');
- });
- $y += $lineHeight; // 下一行的 y 坐标
- }
- // 给图片写入文字(总积分)
- $image->text($totalScore, 90, 310, function (Font $font) use ($fontPath) {
- $font->file($fontPath); // 字体文件地址
- $font->size(30); // 字体大小
- $font->color('#E86D8F');
- $font->align('center');
- });
- // 基础路径
- $basepath = 'images/video_report_learn/'.date('Ymd').'/';
- // 保存路径
- $path = public_path('uploads/'.$basepath);
- // 如果路劲不存在
- if (!is_dir($path)) mkdir($path, 0755, true);
- // 路径组合
- $filename = $courseId.'_'.$uid.'.jpg';
- // 保存图片
- $image->encode('jpg', 90)->save($path.$filename);
- // 下发路径
- $path = path_compat($basepath.$filename);
- // 返回路径
- return json_send(['code' => 'success', 'msg' => '生成成功', 'data' => ['image_url' => $path.'?t='.time(),'title'=>$courseName]]);
- } catch (\Throwable $th) {
- // 返回路径
- return json_send(['code' => 'error', 'msg' => $th->getMessage()]);
- }
- }
- //获取课后分析的答题数量
- public function get_after_study_report_image_share(LearnRecord $learnRecordModel)
- {
- // 登录信息(客户id)
- $uid = $this->checkLogin();
- // 接收参数
- $courseId = request('course_id', 0);
- $url = request('page', 'pages/video/index');
- $size = request('size', 150);
- $scene = request('scene', '');
- $position = 'bottom-left';
- $fontPath = public_path() . '/fonts/msyh14.ttf'; // 指定字体文件路径
- //获取总积分(客户)
- $totalQuestionNum = $learnRecordModel->query()->where([['course_id', '=', $courseId], ['custom_uid', '=', $uid]])->sum('question_total');
- $correctNum = $learnRecordModel->query()->where([['course_id', '=', $courseId], ['custom_uid', '=', $uid]])->sum('isanswer_total');
- $inCorrectNum = $totalQuestionNum - $correctNum;
- $accuracy = $correctNum / $totalQuestionNum * 100;
- try {
- // 加载图片
- $image = Image::make(public_path('uploads/images/default/') . 'analysis_report_share_base.png');
- // 生成小程序二维码
- $qrcode = Mini::getUnlimit($scene, ['page' => $url, 'width' => $size, 'is_hyaline' => true]);
- // 错误提示
- if (isset($qrcode['error'])) return json_send(['code' => 'error', 'msg' => $qrcode['error']]);
- // 加载图片 压缩
- $qrcode = $size < 280 ? Image::make($qrcode)->resize($size, $size) : Image::make($qrcode);
- //插入二维码图片
- $image->insert($qrcode, $position, 20, 20);
- // 给图片写入文字总题数:
- $image->text($totalQuestionNum . '题', 260, 300, function (Font $font) use ($fontPath) {
- $font->file($fontPath); // 字体文件地址
- $font->size(24); // 字体大小
- $font->color('#FF7B01');
- $font->align('left');
- });
- // 给图片写入文字正确题数
- $image->text($correctNum . '题', 290, 388, function (Font $font) use ($fontPath) {
- $font->file($fontPath); // 字体文件地址
- $font->size(24); // 字体大小
- $font->color('#0E670F');
- $font->align('left');
- });
- // 给图片写入文字错误题数
- $image->text($inCorrectNum . '题', 290, 476, function (Font $font) use ($fontPath) {
- $font->file($fontPath); // 字体文件地址
- $font->size(24); // 字体大小
- $font->color('#FF0101');
- $font->align('left');
- });
- // 给图片写入文字 正确率
- $image->text($accuracy . '%', 100, 582, function (Font $font) use ($fontPath) {
- $font->file($fontPath); // 字体文件地址
- $font->size(36); // 字体大小
- $font->color('#FA9517');
- $font->align('left');
- });
- // 图片转二进制
- $image = $image->encode('jpg', 90)->__toString();
- // 转base64
- $base64 = 'data:image/jpg;base64,' . base64_encode($image);
- // 返回
- return json_send(['code' => 'success', 'msg' => '生成成功', 'data' => ['base64_image' => $base64]]);
- } catch (\Throwable $th) {
- // 返回
- return json_send(['code' => 'error', 'msg' => $th->getMessage()]);
- }
- }
- // 截断文字并添加省略号
- function truncateText($text, $fontFile, $fontSize, $maxWidth)
- {
- $lines = [];
- $textLength = mb_strlen($text);
- $charIndex = 0;
- // 第一行
- $firstLine = '';
- while ($charIndex < $textLength) {
- $firstLine .= mb_substr($text, $charIndex, 1);
- $testBox = imagettfbbox($fontSize, 0, $fontFile, $firstLine);
- $testWidth = abs($testBox[2] - $testBox[0]);
- if ($testWidth > $maxWidth) {
- // 第一行超出宽度,截断
- $firstLine = mb_substr($firstLine, 0, -1);
- break;
- }
- $charIndex++;
- }
- // 第一行没有超出宽度,直接添加到结果中
- $lines[] = $firstLine;
- // 第二行
- if ($charIndex < $textLength) {
- $secondLine = mb_substr($text, $charIndex);
- $testBox = imagettfbbox($fontSize, 0, $fontFile, $secondLine);
- $testWidth = abs($testBox[2] - $testBox[0]);
- if ($testWidth > $maxWidth) {
- // 第二行超出宽度,截断并添加省略号
- while ($charIndex < $textLength) {
- $secondLine = mb_substr($secondLine, 0, -1);
- $testBox = imagettfbbox($fontSize, 0, $fontFile, $secondLine);
- $testWidth = abs($testBox[2] - $testBox[0]);
- if ($testWidth <= $maxWidth) {
- $secondLine .= '...';
- break;
- }
- }
- }
- $lines[] = $secondLine;
- }
- return $lines;
- }
- }
|