diff --git a/app/Console/Commands/AutoSchoolmate.php b/app/Console/Commands/AutoSchoolmate.php index a2cfb21..1fc7cbd 100755 --- a/app/Console/Commands/AutoSchoolmate.php +++ b/app/Console/Commands/AutoSchoolmate.php @@ -45,18 +45,38 @@ class AutoSchoolmate extends Command */ public function handle() { - // 获取今天上课的课程 + // 获取所有已开始且需要自动加入校友库的课程 $today = date('Y-m-d'); - $courses = Course::where('start_date', $today)->where('auto_schoolmate', 1)->get(); + $courses = Course::where('auto_schoolmate', 1) + ->where(function ($query) use ($today) { + // 方式1: start_date 已填写且 <= 今天 + $query->where(function ($q) use ($today) { + $q->whereNotNull('start_date') + ->where('start_date', '<=', $today); + }) + // 方式2: 或者课程状态为进行中(即使 start_date 未及时填写) + ->orWhere('course_status', 10); + }) + ->get(); + + $totalUpdated = 0; foreach ($courses as $course) { // 获取报名通过的学员 $courseSigns = CourseSign::where('course_id', $course->id)->where('status', 1)->get(); - // 用户设置成校友 - User::whereIn('id', $courseSigns->pluck('user_id')) + if ($courseSigns->isEmpty()) { + continue; + } + + // 只更新还不是校友的学员,避免重复处理 + $updated = User::whereIn('id', $courseSigns->pluck('user_id')) + ->where('is_schoolmate', '!=', 1) //->where('is_black',0) ->update(['is_schoolmate' => 1]); + + $totalUpdated += $updated; } - return $this->info('更新完成'); + + return $this->info("更新完成,共处理 {$totalUpdated} 位学员"); } } diff --git a/app/Console/Commands/SyncTeacherDirection.php b/app/Console/Commands/SyncTeacherDirection.php new file mode 100644 index 0000000..0dfb31b --- /dev/null +++ b/app/Console/Commands/SyncTeacherDirection.php @@ -0,0 +1,124 @@ +info('开始同步老师课程方向...'); + + // 获取所有有课程内容的老师 + $teachers = Teacher::whereHas('courseContents', function ($query) { + $query->whereNotNull('direction') + ->where('direction', '!=', ''); + })->get(); + + $total = $teachers->count(); + if ($total == 0) { + return $this->info('没有需要同步的老师'); + } + + $this->info("共找到 {$total} 个老师需要同步"); + $bar = $this->output->createProgressBar($total); + $bar->start(); + + $updatedCount = 0; + foreach ($teachers as $teacher) { + // 获取该老师所有课程内容的direction + $courseContents = CourseContent::where('teacher_id', $teacher->id) + ->whereNotNull('direction') + ->where('direction', '!=', '') + ->get(); + + if ($courseContents->isEmpty()) { + $bar->advance(); + continue; + } + + // 收集所有direction值 + $allDirections = []; + foreach ($courseContents as $content) { + if (!empty($content->direction)) { + // 将逗号分隔的字符串拆分成数组 + $directions = explode(',', $content->direction); + foreach ($directions as $direction) { + $direction = trim($direction); + if (!empty($direction)) { + $allDirections[] = $direction; + } + } + } + } + + if (empty($allDirections)) { + $bar->advance(); + continue; + } + + // 去重并合并现有direction + $existingDirections = []; + if (!empty($teacher->direction)) { + $existingDirections = array_map('trim', explode(',', $teacher->direction)); + $existingDirections = array_filter($existingDirections); + } + + // 合并并去重 + $mergedDirections = array_unique(array_merge($existingDirections, $allDirections)); + $mergedDirections = array_filter($mergedDirections); // 移除空值 + + // 排序并重新组合 + sort($mergedDirections); + $newDirection = implode(',', $mergedDirections); + + // 如果direction有变化,则更新 + if ($teacher->direction !== $newDirection) { + $teacher->direction = $newDirection; + $teacher->save(); + $updatedCount++; + } + + $bar->advance(); + } + + $bar->finish(); + $this->newLine(); + $this->info("同步完成,共更新 {$updatedCount} 个老师的课程方向"); + + return 0; + } +} + diff --git a/app/Console/Commands/UpdateCompany.php b/app/Console/Commands/UpdateCompany.php index 4b5be0c..00be7b9 100755 --- a/app/Console/Commands/UpdateCompany.php +++ b/app/Console/Commands/UpdateCompany.php @@ -4,8 +4,6 @@ namespace App\Console\Commands; use App\Models\Company; use App\Models\User; -use App\Repositories\MeetRepository; -use App\Repositories\YuanheRepository; use Illuminate\Console\Command; @@ -16,7 +14,7 @@ class UpdateCompany extends Command * * @var string */ - protected $signature = 'update_company {--user_id=} {--address=0} {--market=0}'; + protected $signature = 'update_company {--user_id=}'; /** * The console command description. @@ -43,18 +41,8 @@ class UpdateCompany extends Command public function handle() { $user_id = $this->option('user_id'); - $updateLocal = (int)$this->option('address'); - $updateMarket = (int)$this->option('market'); // 更新公司信息 $this->compnay($user_id); - // 更新经纬度信息(可选) - if ($updateLocal) { - $this->local($user_id); - } - // 更新上市状态(可选) - if ($updateMarket) { - $this->updateMarketStatus(); - } return $this->info('全部更新完成'); } @@ -63,19 +51,16 @@ class UpdateCompany extends Command */ public function compnay($user_id = null) { - if ($user_id) { - // 强制单个更新 - $users = User::whereHas('courseSigns', function ($query) { - $query->where('status', 1); - })->where('id', $user_id)->get(); - } else { - // 批量更新(只更新有报名审核通过的用户) - $users = User::whereHas('courseSigns', function ($query) { - $query->where('status', 1); - })->whereNotNull('company_name') - ->whereNull('company_id') - ->get(); - } + // 扫描待更新的用户:company_id = -1(待更新)或 company_id = null(兼容旧数据) + $users = User::whereNotNull('company_name') + ->where(function ($query) use ($user_id) { + if ($user_id) { + $query->where('id', $user_id); + } + })->where(function ($query) { + $query->where('company_id', -1)->orWhereNull('company_id'); + })->orderBy('id', 'desc') + ->get(); $total = $users->count(); if ($total == 0) { @@ -86,178 +71,21 @@ class UpdateCompany extends Command $bar = $this->output->createProgressBar($total); $bar->start(); - $YuanheRepository = new YuanheRepository(); foreach ($users as $user) { - // 获取公司详细信息 - $result = $YuanheRepository->companyInfo(['enterpriseName' => $user->company_name]); - if (!$result) { - $bar->setMessage($user->company_name . ' 公司不存在', 'status'); - $bar->advance(); - continue; - } - // 如果$result['enterpriseName']存在数字,跳过 - if (preg_match('/\d/', $result['enterpriseName'])) { - $bar->setMessage($user->company_name . ' 公司名称包含数字,跳过', 'status'); - $bar->advance(); - continue; - } - if ($result['status'] == '未注册') { - $bar->setMessage($user->company_name . ' 公司未注册,跳过', 'status'); - $bar->advance(); - continue; - } - $where = ['company_name' => $result['enterpriseName']]; - $data = [ - 'company_address' => $result['address'], - 'business_scope' => $result['businessScope'], - 'company_city' => $result['city'], - 'contact_mail' => $result['contactMail'], - 'contact_phone' => $result['contactPhone'], - 'company_area' => $result['country'], - 'credit_code' => $result['creditCode'], - 'enterprise_id' => $result['enterpriseId'], - 'company_name' => $result['enterpriseName'], - 'is_abroad' => $result['isAbroad'], - 'company_market' => $result['isOnStock'], - 'is_yh_invested' => $result['isYhInvested'], - 'logo' => $result['logo'], - 'company_legal_representative' => $result['operName'], - 'company_province' => $result['province'], - 'company_industry' => combineKeyValue($result['qccIndustry']), - 'regist_amount' => $result['registAmount'], - 'regist_capi_type' => $result['registCapiType'], - 'company_date' => $result['startDate'], - 'status' => $result['status'], - 'stock_date' => $result['stockDate'], - 'currency_type' => $result['currencyType'], - 'stock_number' => $result['stockNumber'], - 'stock_type' => $result['stockType'], - 'company_tag' => implode(',', $result['tagList']), - // 更新日期 - 'update_date' => $result['updatedDate'] ?? null, - // 管理平台 - 'project_users' => $result['projectUsers'] ?? null, - // 股东信息 - 'partners' => $result['partners'] ?? null, - ]; - $company = Company::updateOrCreate($where, $data); - // 更新用户关联 - $user->company_id = $company->id; - $user->save(); - // 更新上市状态 - $this->updateMarketStatus($company->id); - $bar->setMessage($result['enterpriseName'] . ' 更新成功', 'status'); - $bar->advance(); - } - - $bar->finish(); - $this->newLine(); - return $this->info('公司信息-全部更新完成'); - } - - /** - * 更新经纬度信息 - */ - public function local($user_id = null) - { - if ($user_id) { - // 强制单个更新 - $user = User::find($user_id); - if (empty($user->company_id)) { - return $this->error('用户没有关联公司'); - } - $companys = Company::where('id', $user->company_id)->get(); - } else { - // 批量更新 - $companys = Company::whereNull('company_longitude') - ->whereNotNUll('company_address') - ->where('company_address', '!=', '') - ->get(); - } - - $total = $companys->count(); - if ($total == 0) { - return $this->info('没有需要更新经纬度的公司'); - } - - $this->info("开始更新经纬度信息,共 {$total} 个公司"); - $bar = $this->output->createProgressBar($total); - $bar->start(); - - // 每3个数据分一个chunk 。接口限制了一秒只能3次请求 - $companysChunk = $companys->chunk(3); - foreach ($companysChunk as $companyChunk) { - foreach ($companyChunk as $item) { - $local = Company::addressTolocation($item->company_address); - $item->company_longitude = $local['lng']; - $item->company_latitude = $local['lat']; - $item->save(); - $bar->setMessage($item->company_name . " 经纬度({$local['lng']}, {$local['lat']})更新成功", 'status'); - $bar->advance(); - } - sleep(1); - } - - $bar->finish(); - $this->newLine(); - return $this->info('经纬度信息-全部更新完成'); - } - - /** - * 根据 company_tag 更新上市状态 - * 判断是否包含上市代码标签,如 688001.SH、000001.SZ、830001.BJ 等 - */ - public function updateMarketStatus($companyId = null) - { - $this->info('开始更新上市状态...'); + // 调用模型方法更新公司信息 + $result = Company::updateCompanyFromUser($user); - // 获取所有有 company_tag 的公司 - if ($companyId) { - $companies = Company::where('id', $companyId)->get(); - } else { - $companies = Company::whereNotNull('company_tag') - ->where('company_tag', '!=', '') - ->get(); - } - - $total = $companies->count(); - if ($total == 0) { - return $this->info('没有需要更新上市状态的公司'); - } - - $bar = $this->output->createProgressBar($total); - $bar->start(); - - // 上市代码正则:匹配全球各地上市公司股票代码后缀 - // 支持的后缀:.SH,.SZ,.BJ,.TW,.HK,.SG,.US,.DE,.FR,.JP,.KR,.N,.O,.A,.PK,.Q,.TO,.AX,.L,.WS,.U,.PR,.B,.DB,.UN,.RT,.WT,.E,.C,.D,.F,.G,.H,.I,.J,.K,.L,.M,.N,.O,.P,.V,.Y,.Z - // 简化匹配:只要字符串中包含分隔符(.)+指定后缀,就算上市(只匹配.开头的,不匹配-开头的) - // 支持格式:688001.SH、AAPG.O、TSLA.US、华兴源创(688001.SH)等 - // 后缀按长度从长到短排序,避免短后缀误匹配 - $stockCodePattern = '/\.(SWR|SW|WR|SS|RS|SB|PK|TO|AX|WS|PR|DB|UN|RT|WT|SH|SZ|BJ|TW|HK|SG|US|DE|FR|JP|KR|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|U|V|W|X|Y|Z)(?![A-Za-z0-9])/i'; - - $updatedCount = 0; - foreach ($companies as $company) { - $hasStockCode = preg_match($stockCodePattern, $company->company_tag); - // 检查是否包含"新三板" - $hasXinsanban = strpos($company->company_tag, '新三板') !== false; - // 如果匹配到股票代码或包含"新三板",则标记为上市 - $newMarketStatus = ($hasStockCode || $hasXinsanban) ? 1 : 0; - - // 只有状态变化才更新 - if ($company->company_market != $newMarketStatus) { - $company->company_market = $newMarketStatus; - $company->save(); - $updatedCount++; - $statusText = $newMarketStatus ? '上市' : '非上市'; - $bar->setMessage("{$company->company_name} => {$statusText}", 'status'); + if ($result['success']) { + $bar->setMessage($result['company']->company_name . ' 更新成功', 'status'); + } else { + $bar->setMessage($user->company_name . ' ' . $result['message'], 'status'); } - $bar->advance(); } $bar->finish(); $this->newLine(); - return $this->info("上市状态更新完成,共更新 {$updatedCount} 个公司"); + return $this->info('公司信息-全部更新完成'); } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index f1b43ea..bf141d1 100755 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -29,7 +29,11 @@ class Kernel extends ConsoleKernel // 更新学员编号 $schedule->command('update_user_no')->dailyAt('00:05'); // 更新课程校友资格 - $schedule->command('auto_schoolmate')->dailyAt('23:50'); + $schedule->command('auto_schoolmate')->everyThirtyMinutes(); + // 更新公司信息 + $schedule->command('update_company')->everyTenMinutes(); + // 同步老师课程方向 + $schedule->command('sync:teacher_direction')->hourly(); } /** diff --git a/app/Http/Controllers/Admin/CompanyController.php b/app/Http/Controllers/Admin/CompanyController.php index 684e1bc..b8510e4 100644 --- a/app/Http/Controllers/Admin/CompanyController.php +++ b/app/Http/Controllers/Admin/CompanyController.php @@ -17,6 +17,7 @@ use App\Models\CustomForm; use App\Models\CustomFormField; use App\Models\EmailTemplate; use App\Models\SupplyDemand; +use App\Models\Teacher; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Validator; use Maatwebsite\Excel\Facades\Excel; @@ -58,7 +59,31 @@ class CompanyController extends BaseController }); $companiesTags = array_values($companiesTags); - return $this->success(compact('companiesTags')); + // 课程方向(从teachers表的direction字段获取并去重) + $teacherDirections = Teacher::whereNotNull('direction') + ->where('direction', '!=', '') + ->pluck('direction') + ->toArray(); + + $allDirections = []; + foreach ($teacherDirections as $direction) { + if (!empty($direction)) { + // 将逗号分隔的字符串拆分成数组 + $directions = explode(',', $direction); + foreach ($directions as $dir) { + $dir = trim($dir); + if (!empty($dir)) { + $allDirections[] = $dir; + } + } + } + } + // 去重并重新索引 + $directions = array_values(array_unique($allDirections)); + // 排序 + sort($directions); + + return $this->success(compact('companiesTags', 'directions')); } diff --git a/app/Http/Controllers/Admin/CourseContentController.php b/app/Http/Controllers/Admin/CourseContentController.php index bc8e77f..082514b 100755 --- a/app/Http/Controllers/Admin/CourseContentController.php +++ b/app/Http/Controllers/Admin/CourseContentController.php @@ -39,6 +39,7 @@ class CourseContentController extends BaseController * @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"), * @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"), * @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"), + * @OA\Parameter(name="direction", in="query", @OA\Schema(type="string"), required=false, description="课程方向多个英文逗号分隔"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", @@ -51,55 +52,69 @@ class CourseContentController extends BaseController $all = request()->all(); $list = $this->model->with($all['show_relation'] ?? []) ->withCount('courseKeeps') - ->withCount(['courseKeeps as user_sign_total' => function ($query) { - $query->where('status', 1); - }])->withCount(['courseKeeps as user_lack_sign_total' => function ($query) { - $query->where('status', 0); - }])->where(function ($query) use ($all) { - if (isset($all['filter']) && !empty($all['filter'])) { - foreach ($all['filter'] as $condition) { - $key = $condition['key'] ?? null; - $op = $condition['op'] ?? null; - $value = $condition['value'] ?? null; - if (!isset($key) || !isset($op) || !isset($value)) { - continue; - } - // 等于 - if ($op == 'eq') { - $query->where($key, $value); - } - // 不等于 - if ($op == 'neq') { - $query->where($key, '!=', $value); - } - // 模糊搜索 - if ($op == 'like') { - $query->where($key, 'like', '%' . $value . '%'); - } - // 否定模糊搜索 - if ($op == 'notlike') { - $query->where($key, 'not like', '%' . $value . '%'); - } - // null搜索 - if ($op == 'null') { - $query->whereNull($key)->orWhereRaw("json_length($key) = 0"); - } - // notnull搜索 - if ($op == 'notnull') { - // 不是null并且不是空json,这个是一个json字段 - $query->whereNotNull($key)->whereRaw("json_length($key) > 0"); - } - // 范围搜索 - if ($op == 'range') { - list($from, $to) = explode(',', $value); - if (empty($from) || empty($to)) { + ->withCount([ + 'courseKeeps as user_sign_total' => function ($query) { + $query->where('status', 1); + } + ])->withCount([ + 'courseKeeps as user_lack_sign_total' => function ($query) { + $query->where('status', 0); + } + ])->where(function ($query) use ($all) { + // 课程方向筛选(支持多选,多个英文逗号分隔) + if (isset($all['direction']) && !empty($all['direction'])) { + $directions = explode(',', $all['direction']); + $query->where(function ($q) use ($directions) { + foreach ($directions as $direction) { + $q->orWhereRaw('FIND_IN_SET(?, direction)', [trim($direction)]); + } + }); + } + + if (isset($all['filter']) && !empty($all['filter'])) { + foreach ($all['filter'] as $condition) { + $key = $condition['key'] ?? null; + $op = $condition['op'] ?? null; + $value = $condition['value'] ?? null; + if (!isset($key) || !isset($op) || !isset($value)) { continue; } - $query->whereBetween($key, [$from, $to]); + // 等于 + if ($op == 'eq') { + $query->where($key, $value); + } + // 不等于 + if ($op == 'neq') { + $query->where($key, '!=', $value); + } + // 模糊搜索 + if ($op == 'like') { + $query->where($key, 'like', '%' . $value . '%'); + } + // 否定模糊搜索 + if ($op == 'notlike') { + $query->where($key, 'not like', '%' . $value . '%'); + } + // null搜索 + if ($op == 'null') { + $query->whereNull($key)->orWhereRaw("json_length($key) = 0"); + } + // notnull搜索 + if ($op == 'notnull') { + // 不是null并且不是空json,这个是一个json字段 + $query->whereNotNull($key)->whereRaw("json_length($key) > 0"); + } + // 范围搜索 + if ($op == 'range') { + list($from, $to) = explode(',', $value); + if (empty($from) || empty($to)) { + continue; + } + $query->whereBetween($key, [$from, $to]); + } } } - } - })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); + })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); if (isset($all['is_export']) && !empty($all['is_export'])) { // 导出文件名字 $list = $list->limit(5000)->get()->toArray(); @@ -280,7 +295,7 @@ class CourseContentController extends BaseController if (!in_array('日期', $keyList)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '日期字段不存在']); } -// if (!in_array('时间', $keyList)) { + // if (!in_array('时间', $keyList)) { // return $this->fail([ResponseCode::ERROR_BUSINESS, '时间字段不存在']); // } if (!in_array('授课老师', $keyList)) { @@ -292,7 +307,7 @@ class CourseContentController extends BaseController if (!in_array('课程主题', $keyList)) { return $this->fail([ResponseCode::ERROR_BUSINESS, '课程主题字段不存在']); } -// if (!in_array('主题方向', $keyList)) { + // if (!in_array('主题方向', $keyList)) { // return $this->fail([ResponseCode::ERROR_BUSINESS, '主题方向字段不存在']); // } // if (!in_array('上课地点', $keyList)) { diff --git a/app/Http/Controllers/Admin/TeacherController.php b/app/Http/Controllers/Admin/TeacherController.php index beb6333..6ca5aff 100755 --- a/app/Http/Controllers/Admin/TeacherController.php +++ b/app/Http/Controllers/Admin/TeacherController.php @@ -38,7 +38,7 @@ class TeacherController extends BaseController * @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"), * @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"), * @OA\Parameter(name="theme", in="query", @OA\Schema(type="string"), required=false, description="主题"), - * @OA\Parameter(name="direction", in="query", @OA\Schema(type="string"), required=false, description="方向"), + * @OA\Parameter(name="direction", in="query", @OA\Schema(type="string"), required=false, description="课程方向多个英文逗号分隔"), * @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=true, description="搜索关键词"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( @@ -112,20 +112,28 @@ class TeacherController extends BaseController })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc'); // 应用与列表一致的筛选 if (isset($all['theme']) || isset($all['direction'])) { - $list = $list->whereHas('courseContents', function ($query) use ($all) { + $list = $list->where(function ($query) use ($all) { + // 筛选 courseContents 的 theme if (isset($all['theme'])) { - $query->where('theme', $all['theme']); + $query->whereHas('courseContents', function ($q) use ($all) { + $q->where('theme', $all['theme']); + }); } - if (isset($all['direction'])) { - $query->where('direction', $all['direction']); + // 只从 teachers 表的 direction 字段筛选 + if (isset($all['direction']) && !empty($all['direction'])) { + $directions = explode(',', $all['direction']); + $query->where(function ($q) use ($directions) { + foreach ($directions as $direction) { + $q->orWhereRaw('FIND_IN_SET(?, direction)', [trim($direction)]); + } + }); } }); } if (isset($all['keyword'])) { $list = $list->where(function ($query) use ($all) { - $query->whereHas('courseContents', function ($query) use ($all) { - $query->where('direction', 'like', '%' . $all['keyword'] . '%'); - })->orWhere('name', 'like', '%' . $all['keyword'] . '%'); + $query->where('name', 'like', '%' . $all['keyword'] . '%') + ->orWhere('direction', 'like', '%' . $all['keyword'] . '%'); }); } if (isset($all['is_export']) && !empty($all['is_export'])) { @@ -142,9 +150,10 @@ class TeacherController extends BaseController 'introduce' => $teacher->introduce ?? '', 'sex' => $teacher->sex ?? '', 'mobile' => $teacher->mobile ?? '', + 'teacher_direction' => $teacher->direction ?? '', 'course_name' => optional($content->course)->name ?? '', 'theme' => $content->theme ?? '', - 'direction' => $content->direction ?? '', + 'course_direction' => $content->direction ?? '', ]; } } else { @@ -154,9 +163,10 @@ class TeacherController extends BaseController 'introduce' => $teacher->introduce ?? '', 'sex' => $teacher->sex ?? '', 'mobile' => $teacher->mobile ?? '', + 'teacher_direction' => $teacher->direction ?? '', 'course_name' => '', 'theme' => '', - 'direction' => '', + 'course_direction' => '', ]; } } @@ -166,9 +176,10 @@ class TeacherController extends BaseController 'introduce' => '老师简介', 'sex' => '性别', 'mobile' => '联系方式', + 'teacher_direction' => '老师课程方向', 'course_name' => '课程名称', 'theme' => '课程主题', - 'direction' => '课程方向', + 'course_direction' => '课程内容方向', ]; $fileName = ($all['file_name'] ?? '老师课程_') . date('YmdHis') . '.xlsx'; return Excel::download(new CommonExport($rows, $exportFields), $fileName); @@ -298,6 +309,7 @@ class TeacherController extends BaseController 'remark' => $item['remark'] ?? '', 'introduce' => $item['introduce'] ?? '', 'mobile' => $item['mobile'] ?? '', + 'direction' => $item['direction'] ?? '', ]; $this->model->updateOrCreate($where, $data); } diff --git a/app/Http/Controllers/Mobile/UserController.php b/app/Http/Controllers/Mobile/UserController.php index 724518a..9250802 100755 --- a/app/Http/Controllers/Mobile/UserController.php +++ b/app/Http/Controllers/Mobile/UserController.php @@ -181,13 +181,14 @@ class UserController extends CommonController if (isset($all['name']) && !empty($all['name'])) { $all['letter'] = strtoupper(Pinyin::abbr(mb_substr($all['name'], 0, 1))[0]); } + $model->fill($all); + $model->save(); // 如果有公司信息,就更新一下公司 if (isset($all['company_name']) && !empty($all['company_name']) && $model->company_name != $all['company_name']) { - // 调用命令行更新 - Artisan::call("update_company --user_id={$model->id}"); + // 设置待更新标记,由定时任务处理 + $model->company_id = -1; + $model->save(); } - $model->fill($all); - $model->save(); // 判断下,如果用户新加入车牌号,并且有未开始或者进行中的预约,则直接预约车牌号 $appointmentModel = Appointment::where('user_id', $this->getUserId()) ->where('status', 1) diff --git a/app/Models/Company.php b/app/Models/Company.php index 0d67a9f..c45044b 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -2,6 +2,8 @@ namespace App\Models; +use App\Repositories\YuanheRepository; + class Company extends SoftDeletesModel { @@ -160,5 +162,146 @@ class Company extends SoftDeletesModel } } + /** + * 根据用户信息更新公司信息 + * @param User $user 用户对象 + * @return array 返回结果 ['success' => bool, 'message' => string, 'company' => Company|null] + */ + public static function updateCompanyFromUser($user) + { + if (!$user || empty($user->company_name)) { + return ['success' => false, 'message' => '用户或公司名称为空', 'company' => null]; + } + + // 如果已经有有效的公司关联(company_id > 0),跳过 + // 允许处理 company_id = -1(待更新)或 null(初始状态)的情况 + if ($user->company_id && $user->company_id > 0) { + return ['success' => false, 'message' => '用户已有公司关联', 'company' => null]; + } + + $YuanheRepository = new YuanheRepository(); + + // 获取公司详细信息 + $result = $YuanheRepository->companyInfo(['enterpriseName' => $user->company_name]); + + if (!$result) { + // 标识一下未匹配到公司,后续可以根据这个字段筛选出未匹配到公司的用户 + $user->company_id = 0; + $user->save(); + return ['success' => false, 'message' => '公司不存在', 'company' => null]; + } + + // 如果$result['enterpriseName']存在数字,跳过 + if (preg_match('/\d/', $result['enterpriseName'])) { + $user->company_id = 0; + $user->save(); + return ['success' => false, 'message' => '公司名称包含数字,跳过', 'company' => null]; + } + + if ($result['status'] == '未注册') { + $user->company_id = 0; + $user->save(); + return ['success' => false, 'message' => '公司未注册,跳过', 'company' => null]; + } + + $where = ['company_name' => $result['enterpriseName']]; + $data = [ + 'company_address' => $result['address'], + 'business_scope' => $result['businessScope'], + 'company_city' => $result['city'], + 'contact_mail' => $result['contactMail'], + 'contact_phone' => $result['contactPhone'], + 'company_area' => $result['country'], + 'credit_code' => $result['creditCode'], + 'enterprise_id' => $result['enterpriseId'], + 'company_name' => $result['enterpriseName'], + 'is_abroad' => $result['isAbroad'], + 'company_market' => $result['isOnStock'], + 'is_yh_invested' => $result['isYhInvested'], + 'logo' => $result['logo'], + 'company_legal_representative' => $result['operName'], + 'company_province' => $result['province'], + 'company_industry' => combineKeyValue($result['qccIndustry']), + 'regist_amount' => $result['registAmount'], + 'regist_capi_type' => $result['registCapiType'], + 'company_date' => $result['startDate'], + 'status' => $result['status'], + 'stock_date' => $result['stockDate'], + 'currency_type' => $result['currencyType'], + 'stock_number' => $result['stockNumber'], + 'stock_type' => $result['stockType'], + 'company_tag' => implode(',', $result['tagList']), + // 更新日期 + 'update_date' => $result['updatedDate'] ?? null, + // 管理平台 + 'project_users' => $result['projectUsers'] ?? null, + // 股东信息 + 'partners' => $result['partners'] ?? null, + ]; + + $company = Company::updateOrCreate($where, $data); + + // 更新用户关联 + $user->company_id = $company->id; + $user->save(); + + // 更新上市状态 + self::updateMarketStatus($company->id); + + // 更新位置 + self::updateLocation($company->id); + + return ['success' => true, 'message' => '更新成功', 'company' => $company]; + } + + /** + * 更新经纬度信息 + * @param int $companyId 公司ID + * @return bool + */ + public static function updateLocation($companyId) + { + $company = Company::find($companyId); + if (!$company || empty($company->company_address) || $company->company_longitude) { + return false; + } + + $local = Company::addressTolocation($company->company_address); + $company->company_longitude = $local['lng']; + $company->company_latitude = $local['lat']; + $company->save(); + return true; + } + + /** + * 根据 company_tag 更新上市状态 + * 判断是否包含上市代码标签,如 688001.SH、000001.SZ、830001.BJ 等 + * @param int $companyId 公司ID + * @return bool 是否更新成功 + */ + public static function updateMarketStatus($companyId) + { + $company = Company::find($companyId); + if (!$company || empty($company->company_tag)) { + return false; + } + + // 上市代码正则:匹配全球各地上市公司股票代码后缀 + $stockCodePattern = '/\.(SWR|SW|WR|SS|RS|SB|PK|TO|AX|WS|PR|DB|UN|RT|WT|SH|SZ|BJ|TW|HK|SG|US|DE|FR|JP|KR|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|U|V|W|X|Y|Z)(?![A-Za-z0-9])/i'; + + $hasStockCode = preg_match($stockCodePattern, $company->company_tag); + // 检查是否包含"新三板" + $hasXinsanban = strpos($company->company_tag, '新三板') !== false; + // 如果匹配到股票代码或包含"新三板",则标记为上市 + $newMarketStatus = ($hasStockCode || $hasXinsanban) ? 1 : 0; + + // 只有状态变化才更新 + if ($company->company_market != $newMarketStatus) { + $company->company_market = $newMarketStatus; + $company->save(); + return true; + } + return false; + } } diff --git a/database/migrations/2026_01_04_114614_add_direction_to_teachers_table.php b/database/migrations/2026_01_04_114614_add_direction_to_teachers_table.php new file mode 100644 index 0000000..01d2133 --- /dev/null +++ b/database/migrations/2026_01_04_114614_add_direction_to_teachers_table.php @@ -0,0 +1,33 @@ +string('direction')->nullable()->after('remark')->comment('课程方向'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('teachers', function (Blueprint $table) { + $table->dropColumn('direction'); + }); + } +}; +