|
@@ -0,0 +1,241 @@
|
|
|
+<?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();
|
|
|
+ $uid = 7741;
|
|
|
+ // 接收参数
|
|
|
+ $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($courseName, 30, 170, function (Font $font) use ($fontPath) {
|
|
|
+// $font->file($fontPath); // 字体文件地址
|
|
|
+// $font->size(24); // 字体大小
|
|
|
+// $font->color('#2B3D7c');
|
|
|
+// $font->align('left');
|
|
|
+// });
|
|
|
+
|
|
|
+ // 给图片写入文字(总积分)
|
|
|
+ $image->text($totalScore, 90, 310, function (Font $font) use ($fontPath) {
|
|
|
+ $font->file($fontPath); // 字体文件地址
|
|
|
+ $font->size(30); // 字体大小
|
|
|
+ $font->color('#E86D8F');
|
|
|
+ $font->align('center');
|
|
|
+ });
|
|
|
+
|
|
|
+ //TODO 测试的时候用
|
|
|
+ //$outputImagePath = public_path('uploads/images/default/output.jpg'); // 替换为你希望保存的路径
|
|
|
+ //$image->save($outputImagePath);
|
|
|
+
|
|
|
+ $image = $image->encode('jpg', 90)->__toString();
|
|
|
+ // 转base64
|
|
|
+ $base64 = 'data:image/jpg;base64,' . base64_encode($image);
|
|
|
+
|
|
|
+ return json_send(['code'=>'success','msg'=>'图片生成成功','data'=>$base64]);
|
|
|
+ //return $base64;
|
|
|
+ } catch (\Throwable $th) {
|
|
|
+ // 返回路径
|
|
|
+ //return ['error'=>$th->getMessage()];
|
|
|
+ return json_send(['code'=>'error','msg'=>'图片生成失败', 'errorCode'=>$th->getMessage()]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取课后分析的答题数量
|
|
|
+ public function get_after_study_report_image_share(LearnRecord $learnRecordModel)
|
|
|
+ {
|
|
|
+
|
|
|
+ // 登录信息(客户id)
|
|
|
+ //$uid = $this->checkLogin();
|
|
|
+ $uid = 7741;
|
|
|
+ // 接收参数
|
|
|
+ $courseId = request('course_id',0);
|
|
|
+
|
|
|
+ //获取总积分(客户)
|
|
|
+ $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;
|
|
|
+
|
|
|
+ $url = 'pages/index/index';
|
|
|
+ $position = 'bottom-left';
|
|
|
+ $size = request('size',150);
|
|
|
+ $scene = request('scene',0);
|
|
|
+
|
|
|
+ $fontPath = public_path().'/fonts/msyh14.ttf';// 指定字体文件路径
|
|
|
+
|
|
|
+ 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 $qrcode;
|
|
|
+
|
|
|
+ if ($size < 280){
|
|
|
+ // 加载图片 压缩
|
|
|
+ $qrcode = Image::make($qrcode)->resize($size,$size);
|
|
|
+ } else{
|
|
|
+ // 加载图片
|
|
|
+ $qrcode = 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');
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //TODO 测试的时候用
|
|
|
+ $outputImagePath = public_path('uploads/images/default/output_ana.jpg'); // 替换为你希望保存的路径
|
|
|
+ $image->save($outputImagePath);
|
|
|
+
|
|
|
+ $image = $image->encode('jpg', 90)->__toString();
|
|
|
+ // 转base64
|
|
|
+ $base64 = 'data:image/jpg;base64,' . base64_encode($image);
|
|
|
+
|
|
|
+ return json_send(['code'=>'success','msg'=>'图片生成成功','data'=>$base64]);
|
|
|
+ } catch (\Throwable $th) {
|
|
|
+ // 返回路径
|
|
|
+ //return ['error'=>$th->getMessage()];
|
|
|
+ return json_send(['code'=>'error','msg'=>'图片生成失败', 'errorCode'=>$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;
|
|
|
+ }
|
|
|
+}
|