Преглед на файлове

学习报告分享图片

zengwei преди 2 месеца
родител
ревизия
481b935b76

+ 0 - 2
.gitignore

@@ -7,11 +7,9 @@
 /storage/framework/testing/*
 /storage/framework/views/*
 /elkconf
-/public/uploads/*
 /public/uploads/product/*
 /public/uploads/score_product/*
 /public/uploads/company/*
-/public/uploads/images/*
 /public/uploads/topic/*
 /vendor
 *.DS_Store

+ 228 - 0
app/Http/Controllers/Api/Video/ExamReportShareImage.php

@@ -0,0 +1,228 @@
+<?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\ExamRecord;
+use Intervention\Image\Facades\Image;
+use Intervention\Image\Gd\Font;
+
+class ExamReportShareImage extends Api
+{
+    //通过课程id获取课程名称
+    public function get_share_image(ExamRecord $examRecordModel, 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 = $examRecordModel->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, 20, 120, function (Font $font) use ($fontPath) {
+                $font->file($fontPath);        // 字体文件地址
+                $font->size(24);            // 字体大小
+                $font->color('#2B3D7c');
+                $font->align('left');
+            });
+
+            // 给图片写入文字
+            $image->text($totalScore, 40, 260, function (Font $font) use ($fontPath) {
+                $font->file($fontPath);        // 字体文件地址
+                $font->size(24);            // 字体大小
+                $font->color('#E86D8F');
+                $font->align('center');
+            });
+
+            //TODO 测试的时候用,接口返回的时候可以关掉
+            /////开始
+            //$outputImagePath = public_path('uploads/images/default/output_exam.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()]);
+        }
+    }
+
+    //获取课后分析的答题数量
+    public function get_after_study_report_image_share(ExamRecord $examRecordModel, $scene)
+    {
+
+        // 登录信息
+        $uid 					= $this->checkLogin();
+        // 接收参数
+        $courseId 					= request('course_id',0);
+
+        //获取总积分(客户)
+        $totalQuestionNum = $examRecordModel->query()->where([['course_id','=',$courseId], ['custom_uid','=',$uid]])->sum('question_total');
+        $correctNum = $examRecordModel->query()->where([['course_id','=',$courseId], ['custom_uid','=',$uid]])->sum('isanswer_total');
+        $inCorrectNum = $totalQuestionNum - $correctNum;
+        $accuracy = (int) $correctNum/$totalQuestionNum;
+
+        $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.jpg');
+
+            // 生成小程序二维码
+            $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');
+            });
+
+            //插入二维码图片
+
+            $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;
+    }
+
+
+}

+ 2 - 2
app/Http/Controllers/Api/Video/LearnRecord.php

@@ -28,9 +28,9 @@ class LearnRecord extends Api{
 		// 查询播放记录
 		$data['id']				= $Model->add($data);
 		// 上报失败
-		if( !$data['id'] )		return json_send(['code'=>'error','msg'=>'创建成功']);
+		if( !$data['id'] )		return json_send(['code'=>'error','msg'=>'创建失败']);
 		// 返回结果
-		return 					json_send(['code'=>'success','msg'=>'创建失败','data'=>$data]);
+		return 					json_send(['code'=>'success','msg'=>'创建成功','data'=>$data]);
 	}
 
 

+ 241 - 0
app/Http/Controllers/Api/Video/LearnReportShareImage.php

@@ -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;
+    }
+}

BIN
public/uploads/images/default/analysis_report_share_base.png


BIN
public/uploads/images/default/learn_report_share_base.png


+ 13 - 1
routes/api.php

@@ -350,4 +350,16 @@ Route::any('redpacket_active/get_reward',[\App\Http\Controllers\Api\Redpacket\Ac
  */
 // 获取列表
 Route::any('redpacket_active_record/get_list',[\App\Http\Controllers\Api\Redpacket\ActiveRecord::class,'get_list']);
-Route::any('redpacket_active_record/get_list_all',[\App\Http\Controllers\Api\Redpacket\ActiveRecord::class,'get_list_all']);
+Route::any('redpacket_active_record/get_list_all',[\App\Http\Controllers\Api\Redpacket\ActiveRecord::class,'get_list_all']);
+
+/**
+ * 获取学习中的报告图片
+ */
+Route::any('learn_report_share_image/get', [App\Http\Controllers\Api\Video\LearnReportShareImage::class, 'get_share_image']);
+Route::any('learn_report_share_image/get_after', [App\Http\Controllers\Api\Video\LearnReportShareImage::class, 'get_after_study_report_image_share']);
+
+/**
+ * 获取学习后的报告图片
+ */
+Route::any('exam_report_share_image/get', [App\Http\Controllers\Api\Video\ExamReportShareImage::class, 'get_share_image']);
+Route::any('exam_report_share_image/get_after', [App\Http\Controllers\Api\Video\ExamReportShareImage::class, 'get_after_study_report_image_share']);