|
|
|
|
@ -5,7 +5,9 @@ namespace App\Models;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use EasyWeChat\Factory;
|
|
|
|
|
use EasyWeChat\Kernel\Http\StreamResponse;
|
|
|
|
|
use Illuminate\Filesystem\Filesystem;
|
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
|
|
|
|
|
class Course extends SoftDeletesModel
|
|
|
|
|
{
|
|
|
|
|
@ -30,59 +32,70 @@ class Course extends SoftDeletesModel
|
|
|
|
|
public function getStatusTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '待发布', 1 => '已发布'];
|
|
|
|
|
return $array[$this->attributes['status']];
|
|
|
|
|
return $array[$this->attributes['status'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getIsFeeTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '免费', 1 => '收费'];
|
|
|
|
|
return $array[$this->attributes['is_fee']];
|
|
|
|
|
return $array[$this->attributes['is_fee'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getIsArrangeTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['is_arrange']];
|
|
|
|
|
return $array[$this->attributes['is_arrange'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getShowTxlTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['show_txl']];
|
|
|
|
|
return $array[$this->attributes['show_txl'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getShowMobileTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['show_mobile']];
|
|
|
|
|
return $array[$this->attributes['show_mobile'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getAutoSchoolmateTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['auto_schoolmate']];
|
|
|
|
|
return $array[$this->attributes['auto_schoolmate'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getFreeEnterSchoolmateTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['free_enter_schoolmate'] ?? 0];
|
|
|
|
|
return $array[$this->attributes['free_enter_schoolmate'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getIsVirtualTextAttribute()
|
|
|
|
|
{
|
|
|
|
|
$array = [0 => '否', 1 => '是'];
|
|
|
|
|
return $array[$this->attributes['is_virtual']];
|
|
|
|
|
return $array[$this->attributes['is_virtual'] ?? 0] ?? '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getQrcodeAttribute($value)
|
|
|
|
|
{
|
|
|
|
|
return $this->getCourseQrcode($this->attributes['id']);
|
|
|
|
|
try {
|
|
|
|
|
return $this->getCourseQrcode($this->attributes['id']);
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Log::warning('course qrcode append failed', [
|
|
|
|
|
'course_id' => $this->attributes['id'] ?? null,
|
|
|
|
|
'message' => $e->getMessage(),
|
|
|
|
|
]);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getTeacherDetailAttribute($value)
|
|
|
|
|
{
|
|
|
|
|
if (empty($this->teacher_id)) {
|
|
|
|
|
return collect();
|
|
|
|
|
}
|
|
|
|
|
$teacherIds = explode(',', $this->teacher_id);
|
|
|
|
|
return Teacher::whereIn('id', $teacherIds)->get();
|
|
|
|
|
}
|
|
|
|
|
@ -228,25 +241,14 @@ class Course extends SoftDeletesModel
|
|
|
|
|
public function getCourseQrcode($courseId)
|
|
|
|
|
{
|
|
|
|
|
$course = Course::find($courseId);
|
|
|
|
|
$path = config('filesystems.disks.public.root') . '/course_qrcode/' . $course->id . '.png';
|
|
|
|
|
$url = config('filesystems.disks.public.url') . '/course_qrcode/' . $course->id . '.png';
|
|
|
|
|
$fileSys = new Filesystem();
|
|
|
|
|
if ($fileSys->exists($path)) {
|
|
|
|
|
return $url;
|
|
|
|
|
if (empty($course)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
$config = [
|
|
|
|
|
'app_id' => \config('app.applet_appid'),
|
|
|
|
|
'secret' => \config('app.applet_secret')
|
|
|
|
|
];
|
|
|
|
|
$app = Factory::miniProgram($config);
|
|
|
|
|
$tmp = $app->app_code->get('packages/course/detail?' . 'id=' . $courseId, [
|
|
|
|
|
'env_version' => "release" // 正式版
|
|
|
|
|
// 'env_version' => "trial" // 体验版
|
|
|
|
|
]);
|
|
|
|
|
$dir = dirname($path);
|
|
|
|
|
$fileSys->ensureDirectoryExists($dir, 0755, true);
|
|
|
|
|
$fileSys->put($path, $tmp);
|
|
|
|
|
return $url;
|
|
|
|
|
return $this->resolveMiniProgramQrcode(
|
|
|
|
|
'course_qrcode/' . $course->id . '.png',
|
|
|
|
|
'packages/course/detail?id=' . $courseId,
|
|
|
|
|
['course_id' => $courseId]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -255,24 +257,14 @@ class Course extends SoftDeletesModel
|
|
|
|
|
public function getCourseCheckQrcode($courseId)
|
|
|
|
|
{
|
|
|
|
|
$course = Course::find($courseId);
|
|
|
|
|
$path = config('filesystems.disks.public.root') . '/course_check_qrcode/' . $course->id . '.png';
|
|
|
|
|
$url = config('filesystems.disks.public.url') . '/course_check_qrcode/' . $course->id . '.png';
|
|
|
|
|
$fileSys = new Filesystem();
|
|
|
|
|
if ($fileSys->exists($path)) {
|
|
|
|
|
return $url;
|
|
|
|
|
if (empty($course)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
$config = [
|
|
|
|
|
'app_id' => \config('app.applet_appid'),
|
|
|
|
|
'secret' => \config('app.applet_secret')
|
|
|
|
|
];
|
|
|
|
|
$app = Factory::miniProgram($config);
|
|
|
|
|
$tmp = $app->app_code->get('packages/sign/course?course_id=' . $courseId, [
|
|
|
|
|
'env_version' => "release" // 正式版
|
|
|
|
|
]);
|
|
|
|
|
$dir = dirname($path);
|
|
|
|
|
$fileSys->ensureDirectoryExists($dir, 0755, true);
|
|
|
|
|
$fileSys->put($path, $tmp);
|
|
|
|
|
return $url;
|
|
|
|
|
return $this->resolveMiniProgramQrcode(
|
|
|
|
|
'course_check_qrcode/' . $course->id . '.png',
|
|
|
|
|
'packages/sign/course?course_id=' . $courseId,
|
|
|
|
|
['course_id' => $courseId]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -281,26 +273,59 @@ class Course extends SoftDeletesModel
|
|
|
|
|
public function getEvaluationQrcode($id)
|
|
|
|
|
{
|
|
|
|
|
$courseContentEvaluation = CourseContentEvaluation::find($id);
|
|
|
|
|
$path = config('filesystems.disks.public.root') . '/course_evaluation_qrcode/' . $courseContentEvaluation->id . '.png';
|
|
|
|
|
$url = config('filesystems.disks.public.url') . '/course_evaluation_qrcode/' . $courseContentEvaluation->id . '.png';
|
|
|
|
|
if (empty($courseContentEvaluation)) {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
return $this->resolveMiniProgramQrcode(
|
|
|
|
|
'course_evaluation_qrcode/' . $courseContentEvaluation->id . '.png',
|
|
|
|
|
'packages/surveyFill/index?id=' . $id,
|
|
|
|
|
['evaluation_id' => $id]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 读取或生成小程序码;微信/缓存失败时返回空字符串,避免列表接口 500
|
|
|
|
|
*/
|
|
|
|
|
protected function resolveMiniProgramQrcode(string $relativePath, string $page, array $context = []): string
|
|
|
|
|
{
|
|
|
|
|
$path = config('filesystems.disks.public.root') . '/' . $relativePath;
|
|
|
|
|
$url = config('filesystems.disks.public.url') . '/' . $relativePath;
|
|
|
|
|
$fileSys = new Filesystem();
|
|
|
|
|
if ($fileSys->exists($path)) {
|
|
|
|
|
return $url;
|
|
|
|
|
}
|
|
|
|
|
$config = [
|
|
|
|
|
'app_id' => \config('app.applet_appid'),
|
|
|
|
|
'secret' => \config('app.applet_secret')
|
|
|
|
|
];
|
|
|
|
|
$app = Factory::miniProgram($config);
|
|
|
|
|
$tmp = $app->app_code->get('packages/surveyFill/index?id=' . $id, [
|
|
|
|
|
// todo:: 版本切换
|
|
|
|
|
'env_version' => "release" // 正式版
|
|
|
|
|
// 'env_version' => "trial" // 体验版
|
|
|
|
|
]);
|
|
|
|
|
$dir = dirname($path);
|
|
|
|
|
$fileSys->ensureDirectoryExists($dir, 0755, true);
|
|
|
|
|
$fileSys->put($path, $tmp);
|
|
|
|
|
return $url;
|
|
|
|
|
|
|
|
|
|
$appId = (string) config('app.applet_appid');
|
|
|
|
|
$secret = (string) config('app.applet_secret');
|
|
|
|
|
if ($appId === '' || $secret === '') {
|
|
|
|
|
Log::warning('mini program qrcode skipped: missing appid/secret', $context);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$app = Factory::miniProgram([
|
|
|
|
|
'app_id' => $appId,
|
|
|
|
|
'secret' => $secret,
|
|
|
|
|
]);
|
|
|
|
|
$tmp = $app->app_code->get($page, [
|
|
|
|
|
'env_version' => 'release',
|
|
|
|
|
]);
|
|
|
|
|
$content = $tmp instanceof StreamResponse ? $tmp->getBodyContents() : (string) $tmp;
|
|
|
|
|
if ($content === '' || str_starts_with(ltrim($content), '{')) {
|
|
|
|
|
Log::warning('mini program qrcode invalid response', $context + [
|
|
|
|
|
'body' => substr($content, 0, 300),
|
|
|
|
|
]);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
$fileSys->ensureDirectoryExists(dirname($path), 0755, true);
|
|
|
|
|
$fileSys->put($path, $content);
|
|
|
|
|
return $url;
|
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
|
Log::warning('mini program qrcode failed', $context + [
|
|
|
|
|
'message' => $e->getMessage(),
|
|
|
|
|
]);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|