master
lion 3 months ago
commit 4fe1057e5d

@ -43,8 +43,8 @@ class UpdateCompany extends Command
public function handle()
{
$user_id = $this->option('user_id');
$updateLocal = (int) $this->option('address');
$updateMarket = (int) $this->option('market');
$updateLocal = (int)$this->option('address');
$updateMarket = (int)$this->option('market');
// 更新公司信息
$this->compnay($user_id);
// 更新经纬度信息(可选)
@ -72,7 +72,9 @@ class UpdateCompany extends Command
// 批量更新(只更新有报名审核通过的用户)
$users = User::whereHas('courseSigns', function ($query) {
$query->where('status', 1);
})->whereNotNull('company_name')->get();
})->whereNotNull('company_name')
->whereNull('company_id')
->get();
}
$total = $users->count();

@ -0,0 +1,247 @@
<?php
namespace App\Console\Commands;
use App\Models\CourseForm;
use App\Models\CourseSign;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
class UpdateUserFromCourseSign extends Command
{
/**
* 限定的手机号列表
*
* @var array
*/
protected $allowedMobiles = [
'18068449126',
'13775025589',
'13372137856',
'15862529818',
'15850007903',
'18662477010',
'13776041671',
'13811803477',
'13816102853',
'18761927103',
'13771899330',
'15850174698',
'13901337246',
'15190599917',
'13601736904',
'18013537727',
'13771990129',
'13862584161',
'18067734553',
'13913088481',
'13382182663',
'15962537089',
'13472506601',
'15366527762',
'17306151525',
'18862122672',
'18768114864',
'13646251927',
'18068036921',
'13962165222',
'13812764284',
'17746389584',
'13813662822',
];
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'update_user_from_course_sign';
/**
* The console command description.
*
* @var string
*/
protected $description = '从报名表获取用户填写的信息填充到user数据表按手机号匹配';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// 根据限定手机号列表查找所有用户
$users = User::whereIn('mobile', $this->allowedMobiles)->get();
if ($users->isEmpty()) {
return $this->error('没有找到符合条件的用户');
}
$this->info("找到 {$users->count()} 个用户需要处理");
$successCount = 0;
$failCount = 0;
foreach ($users as $user) {
$this->newLine();
$this->info("========== 处理用户:{$user->name} (手机号: {$user->mobile}, ID: {$user->id}) ==========");
try {
$this->processUser($user);
$successCount++;
} catch (\Exception $e) {
$this->error("处理用户 {$user->name} 时出错:" . $e->getMessage());
$failCount++;
}
}
$this->newLine();
return $this->info("全部处理完成!成功:{$successCount},失败:{$failCount}");
}
/**
* 处理单个用户
*/
private function processUser($user)
{
$user_id = $user->id;
// 获取该用户的所有报名记录(携带课程及课程类型)
$courseSigns = CourseSign::with('course.typeDetail')
->where('user_id', $user_id)
->whereNotNull('data')
->get();
if ($courseSigns->isEmpty()) {
$this->info('该用户没有报名记录或报名记录中没有数据');
return;
}
$this->info("找到 {$courseSigns->count()} 条报名记录");
// 如果用户报名了多个课程,并且其中包含课程类型是「高研班」或者「攀峰班」的课程
// 则优先使用这些课程的报名信息更新用户
$targetCourseSigns = $courseSigns;
if ($courseSigns->count() > 1) {
$specialCourseSigns = $courseSigns->filter(function ($sign) {
$typeName = $sign->course->typeDetail->name ?? '';
return in_array($typeName, ['高研班', '攀峰班']);
});
if ($specialCourseSigns->isNotEmpty()) {
$this->info('检测到高研班/攀峰班课程报名记录,将优先使用这些课程的报名信息更新用户');
$targetCourseSigns = $specialCourseSigns;
}
}
// 收集所有需要更新的用户字段
$userData = [];
$hasCompanyName = false;
foreach ($targetCourseSigns as $courseSign) {
if (empty($courseSign->data) || !is_array($courseSign->data)) {
continue;
}
// 获取该课程的表单字段配置,建立 field -> belong_user_table 的映射关系
$courseForms = CourseForm::where('course_id', $courseSign->course_id)
->where('belong_user', 1) // 只获取属于用户信息的字段
->whereNotNull('belong_user_table') // 必须有对应的用户表字段
->where('belong_user_table', '!=', '') // 用户表字段不能为空
->get(['field', 'belong_user_table']);
if ($courseForms->isEmpty()) {
continue;
}
// 建立 field -> belong_user_table 的映射关系
$fieldMapping = [];
foreach ($courseForms as $form) {
$fieldMapping[$form->field] = $form->belong_user_table;
}
// 将 data 数组转换为以 field 为 key 的关联数组
$dataArray = [];
foreach ($courseSign->data as $item) {
if (isset($item['field']) && isset($item['value'])) {
$dataArray[$item['field']] = $item['value'];
}
}
// 提取属于用户信息的字段,使用 belong_user_table 作为用户表的字段名
foreach ($fieldMapping as $field => $userTableField) {
if (isset($dataArray[$field]) && $dataArray[$field] !== null && $dataArray[$field] !== '') {
// 如果字段已经在 $userData 中,且新值不为空,则更新(优先使用非空值)
if (!isset($userData[$userTableField]) || empty($userData[$userTableField])) {
$userData[$userTableField] = $dataArray[$field];
}
// 检查是否是公司名字
if ($userTableField === 'company_name') {
$hasCompanyName = true;
}
}
}
}
if (empty($userData)) {
$this->info('没有找到需要更新的用户信息');
return;
}
$this->info('准备更新以下字段:' . implode(', ', array_keys($userData)));
// 更新用户信息
// 根据 User::$coverFields 判断是否需要覆盖更新
foreach ($userData as $key => $value) {
if (!in_array($key, User::$coverFields)) {
// 追加更新(对于非覆盖字段)
$currentValue = $user->$key ?? '';
if (!empty($currentValue)) {
$tempArray = explode(',', $currentValue . ',' . $value);
$tempArray = array_unique(array_filter($tempArray));
$userData[$key] = implode(',', $tempArray);
}
}
}
// 检查公司名字是否发生变化
$oldCompanyName = $user->company_name;
$newCompanyName = $userData['company_name'] ?? null;
// 如果公司名字从无到有,或者发生变化,都需要更新
$companyNameChanged = $hasCompanyName && isset($newCompanyName) &&
(empty($oldCompanyName) || $oldCompanyName != $newCompanyName);
$user->fill($userData);
$user->save();
$this->info('用户信息更新成功');
// 如果公司名字发生变化或新增,调用 UpdateCompany 脚本
if ($companyNameChanged) {
if (empty($oldCompanyName)) {
$this->info("检测到新增公司名字({$newCompanyName}),开始调用 UpdateCompany 脚本更新公司信息...");
} else {
$this->info("检测到公司名字发生变化({$oldCompanyName} -> {$newCompanyName}),开始调用 UpdateCompany 脚本更新公司信息...");
}
Artisan::call("update_company --user_id={$user_id}");
$this->info('公司信息更新完成');
} elseif ($hasCompanyName && isset($newCompanyName)) {
$this->info("公司名字未发生变化({$newCompanyName}),跳过公司信息更新");
}
$this->info('用户更新完成');
}
}

@ -104,7 +104,7 @@ class UpdateUserNo extends Command
$tag = '元禾同事';
// 获取元和员工用户列表
$users = CourseSign::companyJoin(null, null, null, true);
$users = CourseSign::companyJoin(null, null, null, true, false);
$count = 0;
foreach ($users as $user) {

@ -396,10 +396,18 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
$header = array_values($this->fields);
$moreFileds = [];
if (empty($clear)) {
if (isset($this->data[0]['data']) && is_array($this->data[0]['data'])) {
$moreHeader = array_column($this->data[0]['data'], 'name');
// 容错,取数据不是空的数组
foreach ($this->data as $value) {
if (!empty($value['data'])) {
$otherData = $value['data'];
break;
}
}
if (isset($otherData) && is_array($otherData)) {
$moreHeader = array_column($otherData, 'name');
$header = array_merge($header, $moreHeader);
$moreFileds = array_column($this->data[0]['data'], 'field');
$moreFileds = array_column($otherData, 'field');
}
}
$newList[] = $header;

@ -122,6 +122,11 @@ class OtherController extends CommonController
*/
public function homeV2()
{
// 默认开始时间
$start_date = CourseType::START_DATE;
// 默认结束日期一年以后
$end_date = date('Y-m-d', strtotime('+10 year'));
// 校友总数
$list['schoolmate_total'] = User::where('is_schoolmate', 1)->count();
// 今年新增校友数
@ -140,12 +145,16 @@ class OtherController extends CommonController
$list['cover_rencai_total'] = CourseSign::rencai();
// 重点上市公司
$list['cover_stock_total'] = CourseSign::shangshi();
// 培养人次1
$start_date = CourseType::START_DATE;
// 默认结束日期一年以后
$end_date = date('Y-m-d', strtotime('+10 year'));
// 培养人次
$list['course_signs_pass'] = CourseSign::courseSignsTotal(null, null, 1);
$list['course_signs_pass'] = CourseSign::courseSignsTotal($start_date, $end_date, 1);
// 培养人数
$list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique(null, null, 1, null, null);
$list['course_signs_pass_unique'] = CourseSign::courseSignsTotalByUnique($start_date, $end_date, 1, null, null);
// 跟班学员数
$list['genban_total'] = CourseSign::genban();
$list['genban_total'] = CourseSign::genban($start_date, $end_date);
// 本月课程
$monthCourses = Calendar::with('course.teacher')
->where('start_time', 'like', '%' . date('Y-m') . '%')
@ -154,10 +163,7 @@ class OtherController extends CommonController
$courseTypes = CourseType::where('is_chart', 1)
->orderBy('sort', 'asc')
->where('is_history', 0)->get();
// 默认开始时间
$start_date = CourseType::START_DATE;
// 默认结束日期一年以后
$end_date = date('Y-m-d', strtotime('+10 year'));
foreach ($courseTypes as $courseType) {
// 历史已开设期数
@ -284,7 +290,7 @@ class OtherController extends CommonController
$list['company_invested_year_total'] = CourseSign::companyInvestedYear($start_date, $end_date, $course_ids);
// 元和员工参与人数
$list['company_join_total'] = CourseSign::companyJoin($start_date, $end_date, $course_ids);
$list['company_join_total'] = CourseSign::companyJoin($start_date, $end_date, $course_ids, false, true);
// 全市干部参与企业
$list['company_ganbu_total'] = CourseSign::ganbu($start_date, $end_date, $course_ids);
// 苏州头部企业
@ -322,7 +328,7 @@ class OtherController extends CommonController
// 被投企业数
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
// 元禾同事数
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id]),
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false, false),
];
}
}
@ -551,7 +557,7 @@ class OtherController extends CommonController
'course_signs_pass' => CourseSign::courseSignsTotal($start_date, $end_date, 1, [$course->id], false, false),
'genban_total' => CourseSign::genban($start_date, $end_date, [$course->id]),
'yh_invested_total' => CourseSign::yhInvested($start_date, $end_date, [$course->id]),
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id]),
'company_join_total' => CourseSign::companyJoin($start_date, $end_date, [$course->id], false, false),
];
}
}
@ -1039,7 +1045,7 @@ class OtherController extends CommonController
case 'company_join_total':
// 元和员工参与人员明细 - 使用模型方法(现在返回的是用户列表)
$users = CourseSign::companyJoin($start_date, $end_date, $course_ids, true);
$users = CourseSign::companyJoin($start_date, $end_date, $course_ids, true, false);
// 加载关联关系
$users->load('company');
foreach ($users as $user) {

@ -16,6 +16,7 @@ use App\Models\CourseContent;
use App\Models\CourseContentCheck;
use App\Models\CourseContentEvaluation;
use App\Models\CourseContentEvaluationForm;
use App\Models\CourseForm;
use App\Models\CourseSign;
use App\Models\CourseType;
use App\Models\Notice;
@ -110,13 +111,23 @@ class CourseController extends CommonController
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$detail = Course::with(['qunImage', 'typeDetail', 'courseForms', 'teacher', 'courseContentEvaluation' => function ($query) {
$query->with(['courseContentEvaluationAsks' => function ($q) {
$q->orderBy('sort', 'asc');
}]);
}])->withCount(['courseSigns as my_user' => function ($query) {
$query->where('user_id', $this->getUserId());
}])->find($all['course_id']);
$detail = Course::with([
'qunImage',
'typeDetail',
'courseForms',
'teacher',
'courseContentEvaluation' => function ($query) {
$query->with([
'courseContentEvaluationAsks' => function ($q) {
$q->orderBy('sort', 'asc');
}
]);
}
])->withCount([
'courseSigns as my_user' => function ($query) {
$query->where('user_id', $this->getUserId());
}
])->find($all['course_id']);
return $this->success($detail);
}
@ -144,9 +155,11 @@ class CourseController extends CommonController
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$detail = CourseContentEvaluation::with(['courseContentEvaluationAsks' => function ($q) {
$q->with('courseContent.teacher')->orderBy('sort', 'asc');
}])->find($all['course_content_evaluation_id']);
$detail = CourseContentEvaluation::with([
'courseContentEvaluationAsks' => function ($q) {
$q->with('courseContent.teacher')->orderBy('sort', 'asc');
}
])->find($all['course_content_evaluation_id']);
return $this->success($detail);
}
@ -199,9 +212,11 @@ class CourseController extends CommonController
$all = \request()->all();
$messages = [
'course_id.required' => '课程id必填',
'data.required' => '表单必填',
];
$validator = Validator::make($all, [
'course_id' => 'required'
'course_id' => 'required',
'data' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
@ -224,6 +239,33 @@ class CourseController extends CommonController
return $this->fail([ResponseCode::ERROR_BUSINESS, '报名已结束']);
}
}
// 检测必填字段
$requiredFields = CourseForm::where('course_id', $all['course_id'])
->where('rule', 'like', '%required%')
->get(['field', 'name']);
if ($requiredFields->count() > 0) {
// 将 data 数组转换为以 field 为 key 的关联数组
$dataArray = [];
if (isset($all['data']) && is_array($all['data'])) {
foreach ($all['data'] as $item) {
if (isset($item['field'])) {
$dataArray[$item['field']] = $item['value'] ?? null;
}
}
}
// 检查必填字段
$missingFields = [];
foreach ($requiredFields as $field) {
$fieldValue = $dataArray[$field->field] ?? null;
// 检查字段是否存在且值不为空null、空字符串视为空0是有效值
if ($fieldValue === null || $fieldValue === '') {
$missingFields[] = $field->name;
}
}
if (!empty($missingFields)) {
return $this->fail([ResponseCode::ERROR_PARAMETER, '以下字段为必填项:' . implode('、', $missingFields)]);
}
}
$result = CourseSign::create([
'is_change' => $all['is_change'] ?? 0,
'course_id' => $all['course_id'],
@ -258,9 +300,11 @@ class CourseController extends CommonController
*/
public function myCourse()
{
$list = Course::with('typeDetail', 'courseContentEvaluation')->with(['courseSigns' => function ($query) {
$query->where('user_id', $this->getUserId());
}])->whereHas('courseSigns', function ($query) {
$list = Course::with('typeDetail', 'courseContentEvaluation')->with([
'courseSigns' => function ($query) {
$query->where('user_id', $this->getUserId());
}
])->whereHas('courseSigns', function ($query) {
$query->where('user_id', $this->getUserId());
})->where('is_virtual', 0)->orderBy('id', 'desc')->paginate($all['page_size'] ?? 20);
return $this->success(compact('list'));
@ -325,11 +369,18 @@ class CourseController extends CommonController
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$detail = CourseContent::with(['course', 'teacher', 'courseKeeps', 'courseContentEvaluation' => function ($query) {
$query->with(['courseContentEvaluationAsks' => function ($q) {
$q->orderBy('sort');
}]);
}])->find($all['course_content_id']);
$detail = CourseContent::with([
'course',
'teacher',
'courseKeeps',
'courseContentEvaluation' => function ($query) {
$query->with([
'courseContentEvaluationAsks' => function ($q) {
$q->orderBy('sort');
}
]);
}
])->find($all['course_content_id']);
return $this->success($detail);
}
@ -569,7 +620,7 @@ class CourseController extends CommonController
// 获取打卡范围,千米
// $content_check_range = Config::getValueByKey('content_check_range');
$courseContent = CourseContent::find($all['course_content_id']);
// $distance = getDistance($courseContent->longitude, $courseContent->latitude, $all['longitude'], $all['latitude']);
// $distance = getDistance($courseContent->longitude, $courseContent->latitude, $all['longitude'], $all['latitude']);
// if ($distance > $content_check_range) {
// return $this->fail([ResponseCode::ERROR_BUSINESS, '超出打卡范围']);
// }
@ -654,7 +705,7 @@ class CourseController extends CommonController
// 获取打卡范围,千米
$content_check_range = Config::getValueByKey('content_check_range');
$course = Course::find($all['course_id']);
// if (empty($course->longitude) || empty($course->latitude)) {
// if (empty($course->longitude) || empty($course->latitude)) {
// return $this->fail([ResponseCode::ERROR_BUSINESS, '请先设置课程经纬度']);
// }
// $distance = getDistance($course->longitude, $course->latitude, $all['longitude'], $all['latitude']);
@ -751,15 +802,17 @@ class CourseController extends CommonController
if ($all['type'] == 2) {
$query->where('status', 1);
}
})->with(['courseSigns' => function ($query) use ($all) {
$query->where('status', 1)->whereHas('course', function ($q) {
$q->where('is_fee', 1);
})->with('course.teacher', 'course.typeDetail')
->orderByRaw("FIELD(fee_status, 1, 0, 2,3)");
if (isset($all['course_id'])) {
$query->where('course_id', $all['course_id']);
})->with([
'courseSigns' => function ($query) use ($all) {
$query->where('status', 1)->whereHas('course', function ($q) {
$q->where('is_fee', 1);
})->with('course.teacher', 'course.typeDetail')
->orderByRaw("FIELD(fee_status, 1, 0, 2,3)");
if (isset($all['course_id'])) {
$query->where('course_id', $all['course_id']);
}
}
}])->where(function ($query) use ($all) {
])->where(function ($query) use ($all) {
if ($all['type'] == 1) {
$query->where('is_schoolmate', 1);
}

@ -90,8 +90,10 @@ class CourseSign extends SoftDeletesModel
$query->where('is_chart', 1);
// 开始结束日期的筛选。or查询
if ($start_date && $end_date) {
$query->whereBetween('start_date', [$start_date, $end_date])
->orWhereBetween('end_date', [$start_date, $end_date]);
$query->where(function ($query) use ($start_date, $end_date) {
$query->whereBetween('start_date', [$start_date, $end_date])
->orWhereBetween('end_date', [$start_date, $end_date]);
});
}
})->whereNotIn('status', [4, 5, 6]);
return $baseQuery;
@ -582,7 +584,7 @@ class CourseSign extends SoftDeletesModel
/**
* 元和员工参人员
*/
public static function companyJoin($start_date = null, $end_date = null, $course_ids = null, $retList = false)
public static function companyJoin($start_date = null, $end_date = null, $course_ids = null, $retList = false, $needHistory = true)
{
$courseSignsQuery = self::getStudentList($start_date, $end_date, null, $course_ids);
$courseSignByType = $courseSignsQuery->get();
@ -618,14 +620,17 @@ class CourseSign extends SoftDeletesModel
} else {
// 基础数据
$baseCount = $list->count();
// 额外数据
$employeeParticipations = EmployeeParticipation::where(function ($query) use ($start_date, $end_date) {
// 开始结束日期的筛选。or查询
if ($start_date && $end_date) {
$query->whereBetween('start_date', [$start_date, $end_date])
->orWhereBetween('end_date', [$start_date, $end_date]);
}
})->where('type', 1)->sum('total');
$employeeParticipations = 0;
if ($needHistory) {
// 额外数据
$employeeParticipations = EmployeeParticipation::where(function ($query) use ($start_date, $end_date) {
// 开始结束日期的筛选。or查询
if ($start_date && $end_date) {
$query->whereBetween('start_date', [$start_date, $end_date])
->orWhereBetween('end_date', [$start_date, $end_date]);
}
})->where('type', 1)->sum('total');
}
// 返回统计数据
return $baseCount + $employeeParticipations;
}

Loading…
Cancel
Save