master
lion 3 weeks ago
parent 8b2102696d
commit 26d68ac730

@ -306,17 +306,29 @@ class CourseController extends BaseController
$model->fill($all); $model->fill($all);
$model->save(); $model->save();
DB::commit(); DB::commit();
// 更改状态 } catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
// 提交后再更新状态;微信小程序码失败不应影响保存成功
try {
$model = Course::updateSignStatus($model->id); $model = Course::updateSignStatus($model->id);
$model = Course::updateStatus($model->id); $model = Course::updateStatus($model->id);
if ($model->status == 1 && $model->start_date) { if ($model->status == 1 && $model->start_date) {
CourseAppointmentTotal::addByCourse($model->id); CourseAppointmentTotal::addByCourse($model->id);
} }
return $this->success($model); } catch (\Throwable $e) {
} catch (\Exception $exception) { \Log::warning('course save post-process failed', [
DB::rollBack(); 'course_id' => $model->id ?? null,
return $this->fail([$exception->getCode(), $exception->getMessage()]); 'message' => $e->getMessage(),
]);
} }
$model = Course::find($model->id);
// 保存接口不强制生成小程序码,避免 Failed to cache access token 误报为保存失败
$model->setAppends(array_values(array_diff($model->getAppends(), ['qrcode'])));
return $this->success($model);
} }
/** /**

@ -5,7 +5,9 @@ namespace App\Models;
use EasyWeChat\Factory; use EasyWeChat\Factory;
use EasyWeChat\Kernel\Http\StreamResponse;
use Illuminate\Filesystem\Filesystem; use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Log;
class Course extends SoftDeletesModel class Course extends SoftDeletesModel
{ {
@ -30,59 +32,70 @@ class Course extends SoftDeletesModel
public function getStatusTextAttribute() public function getStatusTextAttribute()
{ {
$array = [0 => '待发布', 1 => '已发布']; $array = [0 => '待发布', 1 => '已发布'];
return $array[$this->attributes['status']]; return $array[$this->attributes['status'] ?? 0] ?? '';
} }
public function getIsFeeTextAttribute() public function getIsFeeTextAttribute()
{ {
$array = [0 => '免费', 1 => '收费']; $array = [0 => '免费', 1 => '收费'];
return $array[$this->attributes['is_fee']]; return $array[$this->attributes['is_fee'] ?? 0] ?? '';
} }
public function getIsArrangeTextAttribute() public function getIsArrangeTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['is_arrange']]; return $array[$this->attributes['is_arrange'] ?? 0] ?? '';
} }
public function getShowTxlTextAttribute() public function getShowTxlTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['show_txl']]; return $array[$this->attributes['show_txl'] ?? 0] ?? '';
} }
public function getShowMobileTextAttribute() public function getShowMobileTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['show_mobile']]; return $array[$this->attributes['show_mobile'] ?? 0] ?? '';
} }
public function getAutoSchoolmateTextAttribute() public function getAutoSchoolmateTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['auto_schoolmate']]; return $array[$this->attributes['auto_schoolmate'] ?? 0] ?? '';
} }
public function getFreeEnterSchoolmateTextAttribute() public function getFreeEnterSchoolmateTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['free_enter_schoolmate'] ?? 0]; return $array[$this->attributes['free_enter_schoolmate'] ?? 0] ?? '';
} }
public function getIsVirtualTextAttribute() public function getIsVirtualTextAttribute()
{ {
$array = [0 => '否', 1 => '是']; $array = [0 => '否', 1 => '是'];
return $array[$this->attributes['is_virtual']]; return $array[$this->attributes['is_virtual'] ?? 0] ?? '';
} }
public function getQrcodeAttribute($value) 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) public function getTeacherDetailAttribute($value)
{ {
if (empty($this->teacher_id)) {
return collect();
}
$teacherIds = explode(',', $this->teacher_id); $teacherIds = explode(',', $this->teacher_id);
return Teacher::whereIn('id', $teacherIds)->get(); return Teacher::whereIn('id', $teacherIds)->get();
} }
@ -228,25 +241,14 @@ class Course extends SoftDeletesModel
public function getCourseQrcode($courseId) public function getCourseQrcode($courseId)
{ {
$course = Course::find($courseId); $course = Course::find($courseId);
$path = config('filesystems.disks.public.root') . '/course_qrcode/' . $course->id . '.png'; if (empty($course)) {
$url = config('filesystems.disks.public.url') . '/course_qrcode/' . $course->id . '.png'; return '';
$fileSys = new Filesystem();
if ($fileSys->exists($path)) {
return $url;
} }
$config = [ return $this->resolveMiniProgramQrcode(
'app_id' => \config('app.applet_appid'), 'course_qrcode/' . $course->id . '.png',
'secret' => \config('app.applet_secret') 'packages/course/detail?id=' . $courseId,
]; ['course_id' => $courseId]
$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;
} }
/** /**
@ -255,24 +257,14 @@ class Course extends SoftDeletesModel
public function getCourseCheckQrcode($courseId) public function getCourseCheckQrcode($courseId)
{ {
$course = Course::find($courseId); $course = Course::find($courseId);
$path = config('filesystems.disks.public.root') . '/course_check_qrcode/' . $course->id . '.png'; if (empty($course)) {
$url = config('filesystems.disks.public.url') . '/course_check_qrcode/' . $course->id . '.png'; return '';
$fileSys = new Filesystem();
if ($fileSys->exists($path)) {
return $url;
} }
$config = [ return $this->resolveMiniProgramQrcode(
'app_id' => \config('app.applet_appid'), 'course_check_qrcode/' . $course->id . '.png',
'secret' => \config('app.applet_secret') 'packages/sign/course?course_id=' . $courseId,
]; ['course_id' => $courseId]
$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;
} }
/** /**
@ -281,26 +273,59 @@ class Course extends SoftDeletesModel
public function getEvaluationQrcode($id) public function getEvaluationQrcode($id)
{ {
$courseContentEvaluation = CourseContentEvaluation::find($id); $courseContentEvaluation = CourseContentEvaluation::find($id);
$path = config('filesystems.disks.public.root') . '/course_evaluation_qrcode/' . $courseContentEvaluation->id . '.png'; if (empty($courseContentEvaluation)) {
$url = config('filesystems.disks.public.url') . '/course_evaluation_qrcode/' . $courseContentEvaluation->id . '.png'; 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(); $fileSys = new Filesystem();
if ($fileSys->exists($path)) { if ($fileSys->exists($path)) {
return $url; return $url;
} }
$config = [
'app_id' => \config('app.applet_appid'), $appId = (string) config('app.applet_appid');
'secret' => \config('app.applet_secret') $secret = (string) config('app.applet_secret');
]; if ($appId === '' || $secret === '') {
$app = Factory::miniProgram($config); Log::warning('mini program qrcode skipped: missing appid/secret', $context);
$tmp = $app->app_code->get('packages/surveyFill/index?id=' . $id, [ return '';
// todo:: 版本切换 }
'env_version' => "release" // 正式版
// 'env_version' => "trial" // 体验版 try {
]); $app = Factory::miniProgram([
$dir = dirname($path); 'app_id' => $appId,
$fileSys->ensureDirectoryExists($dir, 0755, true); 'secret' => $secret,
$fileSys->put($path, $tmp); ]);
return $url; $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 '';
}
} }
/** /**

Loading…
Cancel
Save