Merge branch 'master' of ssh://47.101.48.251:/data/git/wx.sstbc.com

master
lion 4 months ago
commit 885d889778

@ -44,7 +44,8 @@ class CheckBirthday extends Command
*/
public function handle()
{
$users = User::where('is_schoolmate', 1)->where('birthday', date('Y-m-d'))->get();
$day = date('Y-m');
$users = User::where('is_schoolmate', 1)->where('birthday', 'like', '%' . $day . '%')->get();
foreach ($users as $user) {
Notification::send($user, new BirthdayNotify(['user_id' => $user->id]));
}

@ -1,302 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\Course;
use App\Models\Calendar;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class LinkCoursesToCalendar extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'link:courses-to-calendar';
/**
* The console command description.
*
* @var string
*/
protected $description = '将指定的课程列表关联到calendars日历表';
/**
* 课程列表
*
* @var array
*/
protected $courseList = [
'第三期:张平院士— 6G通信与AI融合',
'高研班|第四期高级科创人才研修班-第七模块',
'高研班|第五期高级科创人才研修班-第五模块',
'校友返校日AI+产业融合创新论坛',
'高研班|第六期高级科创人才研修班-第三模块',
'第二课堂|走进珂玛科技',
'人才培训|省科技厅高级技术经理人专班-开学模块',
'初创班|首期技术经理人领航班-第一模块',
'专题培训|苏州市科技企业资本运作公开课',
'初创班|首期高校科技成果转化班-第一模块',
'高研班|第五期高级科创人才研修班-毕业模块',
'高研班|第四期高级科创人才研修班-第八模块',
'第二课堂|走进世华科技',
'初创班|首期高校科技成果转化班-第二模块',
'高研班|第六期高级科创人才研修班-第四模块',
'人才培训|省科技厅高级技术经理人专班-实践模块',
'初创班|首期技术经理人领航班-第二模块',
'攀峰班|首期苏州科技企业资本运作研修班-开学模块',
'初创班|首期技术经理人领航班-结业模块',
'高研班|第七期高级科创人才研修班-开学模块',
'产业加速营|具身智能极客营-开学模块',
'产业加速营|苏州市人工智能潜在独角兽训练营-开学模块',
'初创班|首期高校科技成果转化班-结业模块',
'第二课堂|走进姑苏区',
'高研班|第六期高级科创人才研修班-第五模块',
'产业加速营|苏州市人工智能潜在独角兽训练营-第二模块',
'夏令营2025年度小科学家夏令营',
'攀峰班|首期苏州科技企业资本运作研修班-第二模块',
'产业加速营|苏州市人工智能潜在独角兽训练营-第三模块',
'人才培训|江苏青年科技人才"U35青创学院"培训',
'高研班|第七期高级科创人才研修班-第二模块',
'第二课堂|走进科沃斯',
'高研班|第四期高级科创人才研修班-开学模块',
'高研班|第三期高级科创人才研修班-结业模块',
'第二课堂|走进永鼎',
'第二课堂|走进旭创',
'高研班|第五期高级科创人才研修班-开学模块',
'高研班|第四期高级科创人才研修班-第二模块',
'第二课堂|走进亨通',
'第二课堂|走进企查查',
'科技大讲堂|第一期: 凯文凯利、丁文江院士领衔',
'高研班|第四期高级科创人才研修班-第三模块',
'第二课堂|走进华为苏研所',
'人才培训2024年姑苏领军人才培育营',
'专题培训|苏州市标杆孵化器培训',
'高研班|第五期高级科创人才研修班-第一模块',
'第二课堂|走进亚盛医药',
'第二课堂|新加坡海外游学',
'第二课堂|走进苏州市市场监督管理局',
'第二课堂|走进信达生物',
'人才培训|江苏省高层次人才专题培训',
'夏令营2024年度小科学家夏令营',
'高研班|第五期高级科创人才研修班-第二模块',
'高研班|第四期高级科创人才研修班-第四模块',
'专题培训|太仓市国资审计高质量发展专题培训',
'第二课堂|走进天准科技',
'高研班|第五期高级科创人才研修班-第三模块',
'科技金融沙龙|上海交通大学新能源沙龙',
'科技大讲堂|第二期:伊雷娜·克罗宁解析空间计算',
'人才培训|苏州市科技企业孵化器沙龙',
'高研班|第四期高级科创人才研修班-第五模块',
'人才培训|苏州乡镇党委书记专题研修班',
'科技金融沙龙|资本市场新机遇研讨沙龙',
'产业加速营|人工智能产业加速营',
'高研班|第六期高级科创人才研修班-开学模块',
'第二课堂|走进苏州市低空经济发展展示馆',
'高研班|第四期高级科创人才研修班-第六模块',
'人才培训2024姑苏领军人才创业营',
'产业加速营|集成电路产业专班',
'专题培训关税与出海应对2025美国新政',
'高研班|第五期高级科创人才研修班-第四模块',
'高研班|第六期高级科创人才研修班-第二模块',
];
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info("开始将课程关联到calendars日历表...");
$this->info("总共需要处理 " . count($this->courseList) . " 个课程");
$linkedCount = 0;
$notFoundCourses = [];
$alreadyLinkedCourses = [];
DB::beginTransaction();
try {
foreach ($this->courseList as $courseName) {
$this->info("正在处理课程: {$courseName}");
// 查找匹配的课程
$course = $this->findCourse($courseName);
if (!$course) {
$this->warn("✗ 未找到匹配的课程: {$courseName}");
$notFoundCourses[] = $courseName;
continue;
}
$this->info("✓ 找到匹配课程: {$course->name} (ID: {$course->id})");
// 检查是否已经存在日历记录
$existingCalendar = Calendar::where('course_id', $course->id)
->where('type', 1) // 类型1为课程
->first();
if ($existingCalendar) {
$this->warn("⚠ 课程已存在日历记录: {$course->name}");
$alreadyLinkedCourses[] = $course->name;
continue;
}
// 创建日历记录
$calendarData = $this->createCalendarData($course);
$calendar = Calendar::create($calendarData);
$this->info("✓ 成功创建日历记录 (ID: {$calendar->id}) 关联课程: {$course->name}");
$linkedCount++;
}
DB::commit();
$this->info("\n" . str_repeat('=', 60));
$this->info("处理完成!");
$this->info("成功关联课程数量: {$linkedCount}");
$this->info("已存在日历记录: " . count($alreadyLinkedCourses));
$this->info("未找到匹配课程: " . count($notFoundCourses));
// 显示未找到的课程
if (!empty($notFoundCourses)) {
$this->warn("\n未找到匹配的课程列表:");
foreach ($notFoundCourses as $course) {
$this->warn(" - {$course}");
}
}
// 显示已存在日历记录的课程
if (!empty($alreadyLinkedCourses)) {
$this->warn("\n已存在日历记录的课程列表:");
foreach ($alreadyLinkedCourses as $course) {
$this->warn(" - {$course}");
}
}
} catch (\Exception $e) {
DB::rollback();
$this->error("处理过程中发生错误: " . $e->getMessage());
$this->error("已回滚所有更改");
return;
}
$this->info("\n所有操作已完成");
}
/**
* 查找匹配的课程
*/
private function findCourse($courseName)
{
// 1. 精确匹配
$course = Course::where('name', $courseName)
->whereNull('deleted_at')
->first();
if ($course) {
return $course;
}
// 2. 模糊匹配
$course = Course::where('name', 'like', "%{$courseName}%")
->whereNull('deleted_at')
->first();
if ($course) {
$this->info("通过模糊匹配找到课程: '{$course->name}'");
return $course;
}
// 3. 相似度匹配
$courses = Course::whereNull('deleted_at')
->whereNotNull('name')
->where('name', '!=', '')
->get();
$bestMatch = null;
$highestSimilarity = 0;
foreach ($courses as $course) {
$similarity = $this->calculateSimilarity($courseName, $course->name);
if ($similarity > $highestSimilarity) {
$highestSimilarity = $similarity;
$bestMatch = $course;
}
}
if ($bestMatch && $highestSimilarity > 0.3) { // 设置最低相似度阈值
$this->info("通过相似度匹配找到课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'");
return $bestMatch;
}
return null;
}
/**
* 创建日历数据
*/
private function createCalendarData($course)
{
return [
'type' => 1, // 类型1为课程
'course_id' => $course->id,
'date' => $course->start_date ?? now()->format('Y-m-d'),
'title' => $course->name,
'content' => $course->content ?? '',
'start_time' => $course->start_date ? $course->start_date . ' 09:00:00' : null,
'end_time' => $course->end_date ? $course->end_date . ' 17:00:00' : null,
'url' => $course->url ?? '',
'created_at' => now(),
'updated_at' => now(),
];
}
/**
* 计算字符串相似度
*/
private function calculateSimilarity($str1, $str2)
{
// 移除空格并转换为小写
$str1 = strtolower(preg_replace('/\s+/', '', $str1));
$str2 = strtolower(preg_replace('/\s+/', '', $str2));
if ($str1 === $str2) {
return 1.0;
}
if (empty($str1) || empty($str2)) {
return 0.0;
}
// 使用Levenshtein距离计算相似度
$maxLen = max(strlen($str1), strlen($str2));
if ($maxLen == 0) {
return 1.0;
}
$distance = levenshtein($str1, $str2);
$similarity = 1 - ($distance / $maxLen);
// 如果其中一个字符串包含另一个,提高相似度
if (strpos($str1, $str2) !== false || strpos($str2, $str1) !== false) {
$containsSimilarity = min(strlen($str1), strlen($str2)) / $maxLen;
$similarity = max($similarity, $containsSimilarity);
}
return max(0, $similarity);
}
}

@ -2,6 +2,7 @@
namespace App\Console\Commands;
use App\Models\Calendar;
use App\Models\Course;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
@ -22,7 +23,7 @@ class UpdateCourseUrls extends Command
*
* @var string
*/
protected $description = '从Excel文件读取课程信息匹配phome_ecms_news表的titleurl并更新courses表的url字段';
protected $description = '从Excel文件读取课程信息匹配courses表获取新闻链接并创建calendar记录';
/**
* Create a new command instance.
@ -58,7 +59,9 @@ class UpdateCourseUrls extends Command
$this->info("Excel文件包含 {$sheetCount} 个工作表");
$totalUpdated = 0;
$totalCreated = 0;
$failedCourses = [];
$failedNews = [];
// 处理每个工作表
for ($sheetIndex = 0; $sheetIndex < $sheetCount; $sheetIndex++) {
@ -67,11 +70,29 @@ class UpdateCourseUrls extends Command
$this->info("正在处理工作表: {$sheetName}");
$updated = $this->processWorksheet($worksheet, $sheetName);
$totalUpdated += $updated;
list($created, $sheetFailedCourses, $sheetFailedNews) = $this->processWorksheet($worksheet, $sheetName);
$totalCreated += $created;
$failedCourses = array_merge($failedCourses, $sheetFailedCourses);
$failedNews = array_merge($failedNews, $sheetFailedNews);
}
$this->info("处理完成,总共更新了 {$totalUpdated} 条记录");
$this->info("处理完成,总共创建了 {$totalCreated} 条日历记录");
// 显示匹配失败的课程
if (!empty($failedCourses)) {
$this->warn("匹配失败的课程:");
foreach (array_unique($failedCourses) as $failedCourse) {
$this->warn(" - {$failedCourse}");
}
}
// 显示匹配失败的新闻
if (!empty($failedNews)) {
$this->warn("匹配失败的新闻:");
foreach (array_unique($failedNews) as $failedNewsItem) {
$this->warn(" - {$failedNewsItem}");
}
}
} catch (\Exception $e) {
$this->error("处理Excel文件时发生错误: " . $e->getMessage());
@ -98,70 +119,150 @@ class UpdateCourseUrls extends Command
$headers[$col] = trim($cellValue);
}
$this->info("表头: " . implode(', ', $headers));
// 找到"课程"和"跳转链接"列的位置
// 找到"课程"、"开始时间"、"结束时间"、"跳转链接"列的位置
$courseColumn = null;
$startTimeColumn = null;
$endTimeColumn = null;
$linkColumn = null;
foreach ($headers as $colIndex => $header) {
if (strpos($header, '课程') !== false) {
$courseColumn = $colIndex;
}
if (strpos($header, '开始时间') !== false) {
$startTimeColumn = $colIndex;
}
if (strpos($header, '结束时间') !== false) {
$endTimeColumn = $colIndex;
}
if (strpos($header, '跳转链接') !== false) {
$linkColumn = $colIndex;
}
}
if (!$courseColumn || !$linkColumn) {
$this->warn("工作表 {$sheetName} 中未找到'课程'或'跳转链接'列");
return 0;
if (!$courseColumn || !$startTimeColumn || !$endTimeColumn || !$linkColumn) {
$this->warn("工作表 {$sheetName} 中未找到必要的列(课程、开始时间、结束时间、跳转链接)");
return [0, [], []];
}
$this->info("找到课程列: {$courseColumn},跳转链接列: {$linkColumn}");
$updated = 0;
$this->info("找到课程列: {$courseColumn},开始时间列: {$startTimeColumn},结束时间列: {$endTimeColumn},跳转链接列: {$linkColumn}");
$created = 0;
$failedCourses = [];
$failedNews = [];
// 处理数据行
for ($row = 2; $row <= $highestRow; $row++) {
$courseName = trim($worksheet->getCellByColumnAndRow($courseColumn, $row)->getCalculatedValue());
// 获取开始时间和结束时间的原始值,避免格式化问题
$startTimeCell = $worksheet->getCellByColumnAndRow($startTimeColumn, $row);
$endTimeCell = $worksheet->getCellByColumnAndRow($endTimeColumn, $row);
// 优先使用原始值,如果没有则使用计算值
$startTime = $startTimeCell->getValue();
if ($startTime === null) {
$startTime = trim($startTimeCell->getCalculatedValue());
}
$endTime = $endTimeCell->getValue();
if ($endTime === null) {
$endTime = trim($endTimeCell->getCalculatedValue());
}
$jumpLink = trim($worksheet->getCellByColumnAndRow($linkColumn, $row)->getCalculatedValue());
if (empty($courseName) || empty($jumpLink)) {
if (empty($courseName) || empty($startTime) || empty($endTime)) {
continue;
}
$this->info("处理行 {$row}: 课程='{$courseName}', 跳转链接='{$jumpLink}'");
// 从phome_ecms_news表获取titleurl
list($title, $titleUrl) = $this->getTitleUrlFromNews($jumpLink);
$this->info("处理行 {$row}: 课程='{$courseName}', 开始时间='{$startTime}' (类型: " . gettype($startTime) . "), 结束时间='{$endTime}' (类型: " . gettype($endTime) . "), 跳转链接='{$jumpLink}'");
if ($titleUrl) {
// 更新courses表
$updateCount = $this->updateCourseUrl($courseName, $titleUrl, $title);
$updated += $updateCount;
// 1. 匹配courses表
$courseId = $this->matchCourse($courseName);
if (!$courseId) {
$this->warn("✗ 未找到匹配的课程: '{$courseName}'");
$failedCourses[] = $courseName;
continue;
}
if ($updateCount > 0) {
$this->info("✓ 成功更新课程 '{$courseName}' 的URL为: {$titleUrl}");
} else {
$this->warn("✗ 未找到匹配的课程: '{$courseName}'");
$failedCourses[] = $courseName;
// 2. 匹配phome_ecms_news表获取url和title
$url = null;
$title = null;
if (!empty($jumpLink)) {
list($title, $url) = $this->getTitleUrlFromNews($jumpLink);
if (!$url) {
$this->warn("✗ 未找到匹配的新闻标题: '{$jumpLink}'");
$failedNews[] = $jumpLink;
}
}
// 3. 更新courses表的url字段
if ($url && $title) {
$this->updateCourseUrl($courseId, $url, $title);
}
// 4. 创建calendar记录
$calendarCreated = $this->createCalendarRecord($courseId, $courseName, $startTime, $endTime, $url, $title, $courseName);
if ($calendarCreated) {
$created++;
$this->info("✓ 成功创建日历记录: '{$courseName}'");
} else {
$this->warn("✗ 未找到匹配的新闻标题: '{$jumpLink}'");
$this->warn("✗ 创建日历记录失败: '{$courseName}'");
}
}
// 显示匹配失败的课程
if (!empty($failedCourses)) {
$this->warn("工作表 {$sheetName} 中匹配失败的课程:");
foreach ($failedCourses as $failedCourse) {
$this->warn(" - {$failedCourse}");
return [$created, $failedCourses, $failedNews];
}
/**
* 匹配courses表
*/
private function matchCourse($courseName)
{
try {
// 直接匹配
$course = Course::where('name', $courseName)->first();
if ($course) {
$this->info("通过直接匹配找到课程: '{$course->name}' (ID: {$course->id})");
return $course->id;
}
// 模糊匹配
$course = Course::where('name', 'like', "%{$courseName}%")
->whereNull('deleted_at')
->first();
if ($course) {
$this->info("通过模糊匹配找到课程: '{$course->name}' (ID: {$course->id})");
return $course->id;
}
// 使用相似度匹配
$courses = Course::whereNotNull('name')->where('name', '!=', '')->get();
$bestMatch = null;
$highestSimilarity = 0;
foreach ($courses as $course) {
$similarity = $this->calculateSimilarity($courseName, $course->name);
if ($similarity > $highestSimilarity) {
$highestSimilarity = $similarity;
$bestMatch = $course;
}
}
// 取相似度最高的作为结果,不设置阈值限制
if ($bestMatch && $highestSimilarity > 0.3) {
$this->info("通过相似度匹配找到课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}' (ID: {$bestMatch->id})");
return $bestMatch->id;
}
} catch (\Exception $e) {
$this->error("查询courses表时发生错误: " . $e->getMessage());
}
return $updated;
return null;
}
/**
@ -208,8 +309,9 @@ class UpdateCourseUrls extends Command
}
}
if ($bestMatch && $highestSimilarity > 0) {
$this->info("通过相似度匹配找到 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->title}' -> '{$bestMatch->titleurl}'");
// 取相似度最高的作为结果,不设置阈值限制
if ($bestMatch && $highestSimilarity > 0.3) {
$this->info("通过相似度匹配找到新闻 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->title}' -> '{$bestMatch->titleurl}'");
return [$bestMatch->title, $bestMatch->titleurl];
}
@ -223,58 +325,130 @@ class UpdateCourseUrls extends Command
/**
* 更新courses表的url字段
*/
private function updateCourseUrl($courseName, $titleUrl, $title)
private function updateCourseUrl($courseId, $titleUrl, $title)
{
try {
// 直接匹配
$updateCount = Course::where('name', $courseName)
->whereNull('deleted_at')
->update(['url' => $titleUrl, 'url_title' => $title]);
$course = Course::find($courseId);
if ($course) {
$course->url = $titleUrl;
$course->url_title = $title;
$course->save();
$this->info("✓ 成功更新课程URL: '{$course->name}' -> '{$titleUrl}'");
return true;
}
} catch (\Exception $e) {
$this->error("更新courses表时发生错误: " . $e->getMessage());
}
return false;
}
/**
* 创建calendar记录
*/
private function createCalendarRecord($courseId, $courseName, $startTime, $endTime, $url = null, $title = null, $calendarTitle = null)
{
try {
// 转换时间格式
$startDateTime = $this->parseDateTime($startTime);
$endDateTime = $this->parseDateTime($endTime);
if ($updateCount > 0) {
return $updateCount;
if (!$startDateTime || !$endDateTime) {
$this->warn("时间格式解析失败: 开始时间='{$startTime}', 结束时间='{$endTime}'");
return false;
}
// 模糊匹配
$updateCount = Course::where('name', 'like', "%{$courseName}%")
->whereNull('deleted_at')
->update(['url' => $titleUrl, 'url_title' => $title]);
// 检查是否已存在相同的日历记录
$existingCalendar = Calendar::where('course_id', $courseId)
->where('start_time', $startDateTime)
->where('end_time', $endDateTime)
->first();
if ($updateCount > 0) {
$this->info("通过模糊匹配更新了课程");
return $updateCount;
if ($existingCalendar) {
$this->info("日历记录已存在,跳过创建: '{$courseName}'");
return true;
}
// 使用相似度匹配
$courses = Course::whereNull('deleted_at')
->whereNotNull('name')
->where('name', '!=', '')
->get();
// 创建新的日历记录
$calendar = new Calendar();
$calendar->type = 1; // 课程类型
$calendar->course_id = $courseId;
$calendar->title = $calendarTitle ?: $courseName; // 使用Excel中的课程名字作为title
$calendar->start_time = $startDateTime;
$calendar->end_time = $endDateTime;
$calendar->date = $startDateTime->format('Y-m-d');
$calendar->url = $url;
$calendar->is_publish = 1; // 默认发布
$calendar->save();
$bestMatch = null;
$highestSimilarity = 0;
return true;
foreach ($courses as $course) {
$similarity = $this->calculateSimilarity($courseName, $course->name);
if ($similarity > $highestSimilarity) {
$highestSimilarity = $similarity;
$bestMatch = $course;
} catch (\Exception $e) {
$this->error("创建calendar记录时发生错误: " . $e->getMessage());
}
return false;
}
/**
* 解析日期时间格式
*/
private function parseDateTime($dateTimeString)
{
try {
// 处理Excel数字格式的日期时间
if (is_numeric($dateTimeString)) {
$excelDate = (float) $dateTimeString;
// Excel日期从1900年1月1日开始计算天数
// 需要减去2是因为Excel错误地认为1900年是闰年
$unixTimestamp = ($excelDate - 25569) * 86400;
$dateTime = new \DateTime();
$dateTime->setTimestamp($unixTimestamp);
$this->info("Excel数字日期转换: {$dateTimeString} -> " . $dateTime->format('Y-m-d H:i:s'));
return $dateTime;
}
// 尝试多种日期时间格式
$formats = [
'Y-m-d H:i:s',
'Y-m-d H:i',
'Y/m/d H:i:s',
'Y/m/d H:i',
'Y-m-d',
'Y/m/d',
'd/m/Y H:i:s',
'd/m/Y H:i',
'd-m-Y H:i:s',
'd-m-Y H:i'
];
foreach ($formats as $format) {
$dateTime = \DateTime::createFromFormat($format, $dateTimeString);
if ($dateTime !== false) {
// 如果只有日期没有时间,设置默认时间
if (strpos($format, 'H:i') === false) {
$dateTime->setTime(9, 0, 0); // 默认上午9点
}
return $dateTime;
}
}
if ($bestMatch && $highestSimilarity > 0) {
$bestMatch->url = $titleUrl;
$bestMatch->url_title = $title;
$bestMatch->save();
$this->info("通过相似度匹配更新了课程 (相似度: " . round($highestSimilarity * 100, 2) . "%): '{$bestMatch->name}'");
return 1;
// 尝试使用strtotime
$timestamp = strtotime($dateTimeString);
if ($timestamp !== false) {
$dateTime = new \DateTime();
$dateTime->setTimestamp($timestamp);
return $dateTime;
}
} catch (\Exception $e) {
$this->error("更新courses表时发生错误: " . $e->getMessage());
$this->error("解析日期时间时发生错误: " . $e->getMessage());
}
return 0;
return null;
}
/**

@ -6,6 +6,7 @@ use App\Helpers\ResponseCode;
use App\Models\Admin;
use App\Models\Appointment;
use App\Models\AppointmentConfig;
use App\Models\Calendar;
use App\Models\CarparkLog;
use App\Models\Company;
use App\Models\CourseSign;
@ -121,32 +122,28 @@ class OtherController extends CommonController
// 报名人数
$list['course_signs_total'] = CourseSign::whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->whereNotIn('status', [4, 5])
->where(function ($query) use ($courses) {
$query->whereIn('course_id', $courses->pluck('id'));
})->count();
// 审核通过人数
$list['course_signs_pass'] = CourseSign::where('status', 1)
$courseSign = CourseSign::where('status', 1)
->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->whereNotIn('status', [4, 5])
->where(function ($query) use ($courses) {
$query->whereIn('course_id', $courses->pluck('id'));
})
->count();
})->get();
$list['course_signs_pass'] = $courseSign->count();
// 审核通过人数去重
$list['course_signs_pass_unique'] = CourseSign::where('status', 1)
->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->where(function ($query) use ($courses) {
$query->whereIn('course_id', $courses->pluck('id'));
})->select('user_id')
->distinct()
->count();
$list['course_signs_pass_unique'] = User::whereIn('id', $courseSign->pluck('user_id'))->distinct('mobile')->count();
// 开课场次
$list['course_total'] = $courses->count();
$calendar = Calendar::whereIn('course_id', $courses->pluck('id'))->whereBetween('date', [$start_date, $end_date])->get();
$list['course_total'] = $calendar->count();
// 开课天数
$list['course_day_total'] = $courses->sum(function ($course) {
$start = Carbon::parse($course->start_date);
$end = Carbon::parse($course->end_date);
$list['course_day_total'] = $calendar->sum(function ($course) {
$start = Carbon::parse($course->start_time);
$end = Carbon::parse($course->end_time);
return $end->diffInDays($start) + 1; // 包含起始和结束日期
});
// 返回所有sql语句
@ -160,20 +157,16 @@ class OtherController extends CommonController
->where('start_date', '<=', $end_date)
->where('type', $courseType->id)
->get();
// 培养人数
$courseTypeSignsPass = CourseSign::where('status', 1)
$courseSignByType = CourseSign::where('status', 1)
->whereIn('course_id', $courses2->pluck('id'))
->whereNotIn('status', [4, 5])
->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->count();
->get();
// 培养人数
$courseTypeSignsPass = $courseSignByType->count();
// 去重培养人数
$courseTypeSignsPassUnique = CourseSign::where('status', 1)
->whereIn('course_id', $courses2->pluck('id'))
->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->select('user_id')
->distinct()
->count();
$courseTypeSignsPassUnique = User::whereIn('id', $courseSignByType->pluck('user_id'))->distinct('mobile')->count();
foreach ($courses2 as $course) {
$courseTypesSum[] = [
'course_type' => $courseType->name,
@ -192,20 +185,14 @@ class OtherController extends CommonController
// 区域明细统计
$areas = ParameterDetail::where('parameter_id', 5)->get();
foreach ($areas as $area) {
$area->course_signs_pass = CourseSign::where('status', 1)
$courseSignByArea = CourseSign::where('status', 1)
->whereHas('user', function ($query) use ($area) {
$query->where('company_area', $area->value);
})->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->count();
$area->course_signs_pass_unique = CourseSign::where('status', 1)
->whereHas('user', function ($query) use ($area) {
$query->where('company_area', $area->value);
})->whereDate('created_at', '>=', $start_date)
->whereDate('created_at', '<=', $end_date)
->select('user_id')
->distinct()
->count();
->get();
$area->course_signs_pass = $courseSignByArea->count();
$area->course_signs_pass_unique = User::whereIn('id', $courseSignByArea->pluck('user_id'))->distinct('mobile')->count();
}
return $this->success(compact('list', 'courseTypesSum', 'areas', 'sql'));
}

@ -270,15 +270,16 @@ class SupplyDemandController extends BaseController
$interactionGrowthRate = $this->calculateGrowthRate($interactionCount, $prevInteractionCount);
// 当期供需发布分页
$list = SupplyDemand::with(['user', 'messages' => function ($query) {
$query->with('user', 'toUser')->limit(2)->orderBy('created_at', 'desc');
$list = SupplyDemand::with(['user', 'dialogues' => function ($query) {
$query->with(['user', 'toUser', 'messages' => function ($q) {
$q->orderBy('created_at', 'desc')->limit(10);
}])->limit(2)->orderBy('created_at', 'desc');
}])->where(function ($query) use ($type) {
if ($type) {
$query->where('type', $type);
}
})->whereBetween('created_at', [$startDate, $endDate])
->paginate($all['page_size'] ?? 20);
return $this->success([
'list' => $list,
'supply_demand_count' => $supplyDemandCount,

@ -3,8 +3,12 @@
namespace App\Http\Controllers\Admin;
use App\Exports\BaseExport;
use App\Helpers\ResponseCode;
use App\Models\CustomForm;
use App\Models\CustomFormField;
use App\Models\Teacher;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
class TeacherController extends BaseController
@ -44,7 +48,7 @@ class TeacherController extends BaseController
public function index()
{
$all = request()->all();
$list = $this->model->with('courseContents.course','courseContents.directionDetail')->where(function ($query) use ($all) {
$list = $this->model->with('courseContents.course', 'courseContents.directionDetail')->where(function ($query) use ($all) {
if (isset($all['filter']) && !empty($all['filter'])) {
foreach ($all['filter'] as $condition) {
$key = $condition['key'] ?? null;
@ -224,7 +228,38 @@ class TeacherController extends BaseController
*/
public function import()
{
return parent::import();
$all = \request()->all();
$messages = [
'data.required' => '数据必填',
];
$validator = Validator::make($all, [
'data' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$records = $all['data'];
DB::beginTransaction();
try {
// 获取数据表的所有字段
// 分段导入
foreach ($records as $item) {
$where = ['name' => $item['name']];
$data = [
'name' => $item['name'],
'sex' => $item['sex'] ?? '',
'remark' => $item['remark'] ?? '',
'introduce' => $item['introduce'] ?? '',
'mobile' => $item['mobile'] ?? '',
];
$this->model->updateOrCreate($where, $data);
}
DB::commit();
return $this->success(['total' => count($records), 'filter_total' => count($records)]);
} catch (\Exception $exception) {
DB::rollBack();
return $this->fail([$exception->getCode(), $exception->getMessage()]);
}
}

@ -254,7 +254,7 @@ class UserController extends CommonController
})->where('id', $this->getUserId())->count();
// 是否生日
$is_birthday = 0;
if (isset($user->birthday) && $user->birthday == date('Y-m-d')) {
if (isset($user->birthday) && date('m-d', strtotime($user->birthday)) == date('m-d')) {
$is_birthday = 1;
}
return $this->success(compact('user', 'door_appointments', 'course_signs', 'enter_schoolmate', 'is_birthday'));

@ -15,8 +15,14 @@ class Dialogue extends SoftDeletesModel
return $this->hasOne(User::class, 'id', 'to_user_id');
}
public function supplyDemand(){
public function supplyDemand()
{
return $this->hasOne(SupplyDemand::class, 'id', 'supply_demand_id');
}
public function messages()
{
return $this->hasMany(Message::class, 'dialogue_id', 'id');
}
}

@ -34,5 +34,10 @@ class SupplyDemand extends SoftDeletesModel
return $this->hasMany(Message::class, 'supply_demand_id', 'id');
}
public function dialogues()
{
return $this->hasMany(Dialogue::class, 'supply_demand_id', 'id');
}
}

@ -60,33 +60,46 @@ class CourseContentEvaluationTestDataGenerator
}
// 3) 生成评价问卷主数据
for ($i = 0; $i < $evaluationCount; $i++) {
$courseContent = $allCourseContents->random();
$course = $courses->where('id', $courseContent->course_id)->first();
if (!$course) {
// 如果找不到课程,跳过这个课程内容
continue;
// 按课程分组,每个课程生成一个问卷,包含该课程的所有内容
$coursesWithContents = $courses->map(function ($course) use ($allCourseContents) {
$courseContents = $allCourseContents->where('course_id', $course->id);
return [
'course' => $course,
'contents' => $courseContents
];
})->filter(function ($item) {
return $item['contents']->count() > 0;
});
$selectedCourses = $coursesWithContents->random(min($evaluationCount, $coursesWithContents->count()));
foreach ($selectedCourses as $courseData) {
$course = $courseData['course'];
$courseContents = $courseData['contents'];
// 为每个课程创建一个评价问卷
$evaluation = $this->createEvaluation($courseContents->first(), $course, $faker);
// 4) 为每个问卷生成问题字段(包含该课程的所有内容)
$allAsks = [];
foreach ($courseContents as $courseContent) {
$asks = $this->createEvaluationAsks($evaluation, $courseContent, $course, 0, $faker);
$allAsks = array_merge($allAsks, $asks);
}
$evaluation = $this->createEvaluation($courseContent, $course, $faker);
// 4) 为每个问卷生成问题字段
$askCount = $faker->numberBetween(5, 15);
$asks = $this->createEvaluationAsks($evaluation, $courseContent, $course, $askCount, $faker);
// 5) 生成用户提交的表单数据
$formCount = $faker->numberBetween(10, min(40, $allUsers->count()));
$submittedUsers = $allUsers->random($formCount);
foreach ($submittedUsers as $user) {
$this->createEvaluationForm($evaluation, $user, $asks, $faker);
$this->createEvaluationForm($evaluation, $user, $allAsks, $faker);
}
$log(sprintf('评价问卷#%d "%s" 已生成:%d个问题字段%d份用户提交',
$log(sprintf(
'评价问卷#%d "%s" 已生成:%d个问题字段%d份用户提交',
$evaluation->id,
$evaluation->title,
$askCount,
count($allAsks),
$formCount
));
}
@ -104,11 +117,11 @@ class CourseContentEvaluationTestDataGenerator
$evaluation->title = $this->generateEvaluationTitle($course, $courseContent, $faker);
$evaluation->desc = $this->generateEvaluationDesc($faker);
$evaluation->type_id = $faker->numberBetween(1, 5); // 问卷类型ID
// 时间设置:开始时间在课程内容时间前后,截止时间在开始时间之后
$startTime = $faker->dateTimeBetween('-30 days', '+7 days');
$endTime = $faker->dateTimeBetween($startTime, $startTime->format('Y-m-d H:i:s') . ' +30 days');
$evaluation->start_time = $startTime->format('Y-m-d H:i:s');
$evaluation->end_time = $endTime->format('Y-m-d H:i:s');
$evaluation->status = $faker->randomElement([0, 1]); // 0未发布, 1已发布
@ -124,10 +137,74 @@ class CourseContentEvaluationTestDataGenerator
{
$asks = [];
$fieldTemplates = $this->getEvaluationFieldTemplates();
for ($i = 0; $i < $count; $i++) {
$template = $faker->randomElement($fieldTemplates);
// 为每个课程内容生成4个评价维度的问题课程必要性、理论丰富程度、实践指导意义、讲授能力
$evaluationDimensions = [
'课程必要性',
'理论丰富程度',
'实践指导意义',
'讲授能力'
];
$sort = 1;
// 为每个评价维度创建问题,每个维度都包含课程内容标题
foreach ($evaluationDimensions as $dimension) {
$ask = new CourseContentEvaluationAsk();
$ask->admin_id = $faker->numberBetween(1, 10);
$ask->department_id = $faker->numberBetween(1, 5);
$ask->course_id = $course->id;
$ask->course_content_id = $courseContent->id;
$ask->course_content_evaluation_id = $evaluation->id;
$ask->name = $courseContent->theme . '——' . $dimension;
$ask->field = strtolower(str_replace(' ', '_', $dimension)) . '_' . $courseContent->id;
$ask->edit_input = 'radio';
$ask->rule = 'required';
$ask->sort = $sort++;
$ask->help = "请评价《{$courseContent->theme}》的{$dimension}";
$ask->select_item = ['很不满意', '不满意', '一般', '满意', '很满意'];
$ask->need_fill = true;
$ask->belong_user = false;
$ask->allow_input = false;
$ask->save();
$asks[] = $ask;
}
// 添加建议类问题
$suggestionTemplates = array_filter($fieldTemplates, function ($template) {
return $template['edit_input'] === 'textarea';
});
foreach ($suggestionTemplates as $template) {
$ask = new CourseContentEvaluationAsk();
$ask->admin_id = $faker->numberBetween(1, 10);
$ask->department_id = $faker->numberBetween(1, 5);
$ask->course_id = $course->id;
$ask->course_content_id = $courseContent->id;
$ask->course_content_evaluation_id = $evaluation->id;
$ask->name = $template['name'];
$ask->field = $template['field'];
$ask->edit_input = $template['edit_input'];
$ask->rule = $template['rule'];
$ask->sort = $sort++;
$ask->help = $template['help'];
$ask->select_item = $template['select_item'];
$ask->need_fill = $template['need_fill'];
$ask->belong_user = $template['belong_user'];
$ask->allow_input = $template['allow_input'];
$ask->save();
$asks[] = $ask;
}
// 添加姓名字段
$nameTemplate = array_filter($fieldTemplates, function ($template) {
return $template['field'] === 'student_name';
});
if (!empty($nameTemplate)) {
$template = reset($nameTemplate);
$ask = new CourseContentEvaluationAsk();
$ask->admin_id = $faker->numberBetween(1, 10);
$ask->department_id = $faker->numberBetween(1, 5);
@ -135,20 +212,20 @@ class CourseContentEvaluationTestDataGenerator
$ask->course_content_id = $courseContent->id;
$ask->course_content_evaluation_id = $evaluation->id;
$ask->name = $template['name'];
$ask->field = $template['field'] . '_' . ($i + 1);
$ask->field = $template['field'];
$ask->edit_input = $template['edit_input'];
$ask->rule = $template['rule'];
$ask->sort = $i + 1;
$ask->sort = $sort++;
$ask->help = $template['help'];
$ask->select_item = $template['select_item'];
$ask->need_fill = $template['need_fill'];
$ask->belong_user = $template['belong_user'];
$ask->allow_input = $template['allow_input'];
$ask->save();
$asks[] = $ask;
}
return $asks;
}
@ -158,11 +235,11 @@ class CourseContentEvaluationTestDataGenerator
private function createEvaluationForm(CourseContentEvaluation $evaluation, User $user, array $asks, $faker): void
{
$formData = [];
foreach ($asks as $ask) {
$formData[$ask->field] = $this->generateFieldValue($ask, $faker);
}
$form = new CourseContentEvaluationForm();
$form->course_content_evaluation_id = $evaluation->id;
$form->user_id = $user->id;
@ -178,17 +255,20 @@ class CourseContentEvaluationTestDataGenerator
private function generateEvaluationTitle(Course $course, CourseContent $courseContent, $faker): string
{
$templates = [
'《%s》课程满意度调查',
'%s 教学效果评价',
'%s 学习体验反馈',
'关于 %s 的教学质量评估',
'%s 课程内容评价问卷',
'%s 授课情况调研',
'%s 学员反馈调查'
'首期%s课程满意度调查',
'%s%s班第一次课课程满意度调查',
'%s研修班课程满意度调查',
'%s培训课程满意度调查',
'%s课程满意度调查问卷',
'%s课程评价调查',
'%s学习效果评价调查'
];
$courseName = $course->title ?? '课程';
return sprintf($faker->randomElement($templates), $courseName);
$courseName = $course->name ?? '课程';
$classNames = ['攀峰班', '精英班', '进阶班', '基础班', '高级班'];
$className = $faker->randomElement($classNames);
return sprintf($faker->randomElement($templates), $courseName, $className);
}
/**
@ -197,13 +277,13 @@ class CourseContentEvaluationTestDataGenerator
private function generateEvaluationDesc($faker): string
{
$descriptions = [
'为了提升教学质量,改进课程内容,请您根据实际学习体验,客观填写本次评价问卷。您的宝贵意见将帮助我们持续优化课程设计。',
'此次评价旨在了解您对本课程的学习感受和建议。问卷采用匿名形式,请放心填写真实想法,感谢您的配合!',
'请根据您的实际学习情况,对本次课程的各个方面进行客观评价。您的反馈对我们改进教学方法具有重要意义。',
'为持续提升课程品质,特设立本次学员满意度调查。请您花费几分钟时间,帮助我们了解课程的优点与不足。',
'感谢您参与本次课程学习!为了给后续学员提供更好的学习体验,恳请您如实填写这份评价问卷。'
'为了提升研修班教学质量,改进课程内容,请您根据实际学习体验,客观填写本次评价问卷。您的宝贵意见将帮助我们持续优化课程设计。',
'此次评价旨在了解您对本研修班课程的学习感受和建议。问卷采用匿名形式,请放心填写真实想法,感谢您的配合!',
'请根据您的实际学习情况,对本次研修班课程的各个方面进行客观评价。您的反馈对我们改进教学方法具有重要意义。',
'为持续提升研修班课程品质,特设立本次学员满意度调查。请您花费几分钟时间,帮助我们了解课程的优点与不足。',
'感谢您参与本次研修班课程学习!为了给后续学员提供更好的学习体验,恳请您如实填写这份评价问卷。'
];
return $faker->randomElement($descriptions);
}
@ -214,114 +294,92 @@ class CourseContentEvaluationTestDataGenerator
{
return [
[
'name' => '课程内容满意度',
'field' => 'content_satisfaction',
'name' => '课程必要性',
'field' => 'course_necessity',
'edit_input' => 'radio',
'rule' => 'required',
'help' => '请选择您对课程内容的满意程度',
'select_item' => ['非常满意', '满意', '一般', '不满意', '非常不满意'],
'help' => '请评价该课程的必要性',
'select_item' => ['很不满意', '不满意', '一般', '满意', '很满意'],
'need_fill' => true,
'belong_user' => false,
'allow_input' => false
],
[
'name' => '授课方式评价',
'field' => 'teaching_method',
'name' => '理论丰富程度',
'field' => 'theory_richness',
'edit_input' => 'radio',
'rule' => 'required',
'help' => '请评价老师的授课方式',
'select_item' => ['很好', '好', '一般', '较差', '很差'],
'help' => '请评价课程理论的丰富程度',
'select_item' => ['很不满意', '不满意', '一般', '满意', '很满意'],
'need_fill' => true,
'belong_user' => false,
'allow_input' => false
],
[
'name' => '课程难度评价',
'field' => 'difficulty_level',
'name' => '实践指导意义',
'field' => 'practical_guidance',
'edit_input' => 'radio',
'rule' => 'required',
'help' => '您认为课程难度如何',
'select_item' => ['太简单', '偏简单', '适中', '偏难', '太难'],
'help' => '请评价课程的实践指导意义',
'select_item' => ['很不满意', '不满意', '一般', '满意', '很满意'],
'need_fill' => true,
'belong_user' => false,
'allow_input' => false
],
[
'name' => '学习收获评价',
'field' => 'learning_gain',
'edit_input' => 'checkbox',
'rule' => '',
'help' => '您在本次学习中获得了哪些收获(可多选)',
'select_item' => ['理论知识', '实践技能', '思维方法', '行业认知', '人际交往', '其他'],
'need_fill' => false,
'belong_user' => false,
'allow_input' => true
],
[
'name' => '课程推荐度',
'field' => 'recommendation',
'name' => '讲授能力',
'field' => 'teaching_ability',
'edit_input' => 'radio',
'rule' => 'required',
'help' => '您是否愿意向他人推荐此课程',
'select_item' => ['非常愿意', '愿意', '无所谓', '不愿意', '绝对不会'],
'help' => '请评价老师的讲授能力',
'select_item' => ['很不满意', '不满意', '一般', '满意', '很满意'],
'need_fill' => true,
'belong_user' => false,
'allow_input' => false
],
[
'name' => '整体评分',
'field' => 'overall_rating',
'edit_input' => 'select',
'rule' => 'required',
'help' => '请为本次课程打分10分制',
'select_item' => ['10分', '9分', '8分', '7分', '6分', '5分', '4分', '3分', '2分', '1分'],
'need_fill' => true,
'name' => '您对本次培训的课程及老师的资料、专业性等方面有哪些建议?',
'field' => 'course_teacher_suggestions',
'edit_input' => 'textarea',
'rule' => '',
'help' => '请提出您对课程和老师的建议',
'select_item' => null,
'need_fill' => false,
'belong_user' => false,
'allow_input' => false
'allow_input' => true
],
[
'name' => '意见建议',
'field' => 'suggestions',
'name' => '您对培训专题、课程内容、授课师资及形式等方面有哪些建议?',
'field' => 'training_suggestions',
'edit_input' => 'textarea',
'rule' => '',
'help' => '请提出您的宝贵意见和建议',
'help' => '请提出您对培训各方面的建议',
'select_item' => null,
'need_fill' => false,
'belong_user' => false,
'allow_input' => true
],
[
'name' => '您的姓名',
'field' => 'student_name',
'edit_input' => 'text',
'name' => '其他建议',
'field' => 'other_suggestions',
'edit_input' => 'textarea',
'rule' => '',
'help' => '请填写您的真实姓名(可选)',
'help' => '请提出其他建议',
'select_item' => null,
'need_fill' => false,
'belong_user' => true,
'allow_input' => false
'belong_user' => false,
'allow_input' => true
],
[
'name' => '联系方式',
'field' => 'contact_info',
'name' => '如果您愿意,请留下您的姓名(选填)',
'field' => 'student_name',
'edit_input' => 'text',
'rule' => '',
'help' => '如需回访,请留下联系方式',
'help' => '这将帮助我们更好地整理反馈并与您沟通',
'select_item' => null,
'need_fill' => false,
'belong_user' => true,
'allow_input' => false
],
[
'name' => '课堂互动评价',
'field' => 'interaction_rating',
'edit_input' => 'radio',
'rule' => '',
'help' => '您对课堂互动环节的评价',
'select_item' => ['很活跃', '较活跃', '一般', '较沉闷', '很沉闷'],
'need_fill' => false,
'belong_user' => false,
'allow_input' => false
]
];
}
@ -335,33 +393,42 @@ class CourseContentEvaluationTestDataGenerator
case 'radio':
case 'select':
return $faker->randomElement($ask->select_item ?? []);
case 'checkbox':
$options = $ask->select_item ?? [];
$selected = $faker->randomElements($options, $faker->numberBetween(1, min(3, count($options))));
return implode(',', $selected);
case 'textarea':
$suggestions = [
'希望增加更多实践环节',
'课程进度可以适当放慢',
'案例分析很有帮助,建议增加',
'老师讲解很清晰,受益良多',
'课程资料很丰富,感谢分享',
'希望提供更多课后练习',
'建议增加小组讨论时间',
'整体非常满意,期待后续课程'
'希望增加更多实践环节和案例分析',
'课程进度可以适当放慢,便于消化吸收',
'案例分析很有帮助,建议增加更多实际案例',
'老师讲解很清晰,理论联系实际,受益良多',
'课程资料很丰富,感谢分享,希望提供更多参考资料',
'希望提供更多课后练习和讨论机会',
'建议增加小组讨论时间和互动环节',
'整体非常满意,期待后续课程,希望继续深入学习',
'课程内容很实用,对工作有很大帮助',
'老师专业水平很高,讲解深入浅出',
'希望增加更多行业前沿信息分享',
'课程安排合理,时间控制得当',
'建议增加更多实战演练环节',
'课程质量很高,值得推荐给同事',
'希望提供更多学习资源和交流平台'
];
return $faker->optional(0.7)->randomElement($suggestions) ?: '';
case 'text':
if ($ask->field === 'student_name') {
return $faker->optional(0.4)->name ?: '';
} elseif ($ask->field === 'course_content_title') {
return $ask->name; // 返回课程内容标题
} elseif ($ask->field === 'contact_info') {
return $faker->optional(0.3)->phoneNumber ?: '';
}
return $faker->optional(0.5)->words(3, true) ?: '';
default:
return '';
}
@ -373,18 +440,62 @@ class CourseContentEvaluationTestDataGenerator
private function createSampleCoursesAndContents($faker): void
{
$courseData = [
['title' => 'Python 程序设计基础', 'contents' => ['Python 语言概述', '数据类型与变量', '控制结构', '函数与模块', '面向对象编程']],
['title' => '数据库原理与应用', 'contents' => ['数据库基础概念', 'SQL 语言基础', '数据库设计', '事务处理', '性能优化']],
['title' => '项目管理实务', 'contents' => ['项目管理概述', '项目计划制定', '风险管理', '团队管理', '项目收尾']],
['title' => '市场营销学', 'contents' => ['市场营销概论', '消费者行为分析', '产品策略', '价格策略', '推广策略']],
['title' => 'Web 前端开发', 'contents' => ['HTML 基础', 'CSS 样式设计', 'JavaScript 编程', 'Vue.js 框架', '项目实战']]
[
'title' => '苏州市科技企业资本运作研修班',
'contents' => [
'《资本市场深化改革背景下,私募股权基金的专业化发展路径与企业家资本战略选择》——王建平老师',
'《科技创新产业现状与未来趋势(深圳创新实践案例)》——梁永生老师',
'《IPO流程与估值——沙盘演练》——郭圣宇老师',
'《IPO流程与估值——沙盘演练》——张剑波老师',
'《IPO企业常见涉税问题——专题授课》——肖鑫老师',
'《IPO企业财务管理——沙盘演练》——王晓苗老师'
]
],
[
'title' => '企业数字化转型研修班',
'contents' => [
'《数字化转型战略规划》——李明老师',
'《人工智能在企业中的应用》——张华老师',
'《大数据分析与决策支持》——王强老师',
'《云计算与云原生架构》——刘伟老师'
]
],
[
'title' => '创新创业管理研修班',
'contents' => [
'《创业机会识别与商业模式设计》——陈刚老师',
'《创业团队建设与管理》——赵敏老师',
'《融资策略与风险投资》——孙涛老师',
'《知识产权保护与运用》——周琳老师'
]
],
[
'title' => '供应链管理研修班',
'contents' => [
'《供应链战略规划》——吴斌老师',
'《采购管理与供应商关系》——郑红老师',
'《物流配送优化》——马超老师',
'《供应链风险管理》——徐静老师'
]
],
[
'title' => '人力资源管理研修班',
'contents' => [
'《人力资源战略规划》——黄磊老师',
'《招聘与人才发展》——韩雪老师',
'《绩效管理与激励机制》——杨帆老师',
'《企业文化与组织发展》——林峰老师'
]
]
];
foreach ($courseData as $data) {
$course = Course::create([
'title' => $data['title'],
'description' => $data['title'] . '课程',
'name' => $data['title'],
'content' => $data['title'] . '课程',
'status' => 1,
'course_status' => 10, // 进行中
'sign_status' => 10, // 进行中
'created_at' => now(),
'updated_at' => now()
]);
@ -392,10 +503,8 @@ class CourseContentEvaluationTestDataGenerator
foreach ($data['contents'] as $index => $contentTitle) {
CourseContent::create([
'course_id' => $course->id,
'title' => $contentTitle,
'description' => $contentTitle . '相关内容',
'sort' => $index + 1,
'status' => 1,
'theme' => $contentTitle,
'period' => '第' . ($index + 1) . '期',
'created_at' => now(),
'updated_at' => now()
]);

Binary file not shown.
Loading…
Cancel
Save