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

master
Your Name 4 months ago
commit 7e54982d59

@ -0,0 +1,70 @@
<?php
namespace App\Console\Commands;
use App\Models\Company;
use App\Models\Course;
use App\Models\User;
use App\Repositories\MeetRepository;
use App\Repositories\YuanheRepository;
use Illuminate\Console\Command;
class PushCourses extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'push_courses';
/**
* The console command description.
*
* @var string
*/
protected $description = '推送课程数据';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$today = date('Y-m-d');
$courses = Course::where('sign_end_date', $today)->whereHas('typeDetail', function ($query) {
$query->where('is_push', 1);
})->get();
if ($courses->isEmpty()) {
$this->info('没有可推送的课程');
return;
}
$YuanheRepository = new YuanheRepository();
foreach ($courses as $course) {
// 所有报名审核成功的用户id
$userIds = $course->courseSigns()->where('status', 1)->pluck('user_id');
$users = User::whereIn('id', $userIds)->whereNotNull('company_id')->get();
foreach ($users as $user) {
$result = $YuanheRepository->pushCourses($course, $user);
if ($result) {
$this->info("推送成功:{$course->name}-{$user->name}");
} else {
$this->info("推送失败:{$course->name}-{$user->name}");
}
}
}
return $this->info('全部更新完成');
}
}

@ -2,6 +2,7 @@
namespace App\Console\Commands;
use App\Models\Company;
use App\Models\User;
use App\Repositories\MeetRepository;
use App\Repositories\YuanheRepository;
@ -15,7 +16,7 @@ class UpdateCompany extends Command
*
* @var string
*/
protected $signature = 'update_company';
protected $signature = 'update_company {--user_id=}';
/**
* The console command description.
@ -41,15 +42,103 @@ class UpdateCompany extends Command
*/
public function handle()
{
$users = User::get();
$user_id = $this->option('user_id');
// 更新公司信息
$this->compnay($user_id);
// 更新经纬度信息
$this->local($user_id);
return $this->info('全部更新完成');
}
/**
* 更新公司信息
*/
public function compnay($user_id = null)
{
if ($user_id) {
// 强制单个更新
$users = User::where('id', $user_id)->get();
} else {
// 批量更新
$users = User::whereDoesntHave('company')->get();
}
$YuanheRepository = new YuanheRepository();
foreach ($users as $user) {
// 获取公司详细信息
$result = $YuanheRepository->companyInfo(['enterpriseName' => $user->company_name]);
dd($result);
if (!$result) {
$this->info($user->company_name . '公司不存在');
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' => $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' => $result['tagList'],
];
$company = Company::updateOrCreate($where, $data);
// 更新用户关联
$user->company_id = $company->id;
$user->save();
$this->info($result['enterpriseName'] . '-更新成功');
}
return $this->info('更新完成');
return $this->info('公司信息-全部更新完成');
}
/**
* 更新经纬度信息
*/
public function local($user_id = null)
{
if ($user_id) {
// 强制单个更新
$user = User::find($user_id);
if (empty($user->company_id)) {
return false;
}
$companys = Company::where('id', $user->company_id)->get();
} else {
// 批量更新
$companys = Company::whereNull('company_longitude')
->whereNotNUll('company_address')
->where('company_address', '!=', '')
->get();
}
// 每3个数据分一个chunk 。接口限制了一秒只能3次请求
$companys = $companys->chunk(3);
foreach ($companys as $company) {
foreach ($company as $item) {
$local = Company::addressTolocation($item->company_address);
$item->company_longitude = $local['lng'];
$item->company_latitude = $local['lat'];
$item->save();
$this->info($item->company_name . "-{$local['lng']}-{$local['lat']}-经纬度信息更新成功");
}
sleep(1);
}
return true;
}
}

@ -24,6 +24,8 @@ class Kernel extends ConsoleKernel
$schedule->command('check_birthday')->dailyAt('09:00');
// 邮件群发
$schedule->command('send_email')->everyMinute();
// 推送课程人员信息
$schedule->command('push_courses')->dailyAt('23:00');
}
/**

@ -150,8 +150,8 @@ class CourseContentController extends BaseController
* @OA\Parameter(name="id", in="query", @OA\Schema(type="integer"), required=true, description="课程ID存在则更新不存在则新增"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="验证token"),
* @OA\Parameter(name="course_id", in="query", @OA\Schema(type="integer"), description="课程ID"),
* @OA\Parameter(name="start_time", in="query", @OA\Schema(type="string"), description="开始时间"),
* @OA\Parameter(name="end_time", in="query", @OA\Schema(type="string"), description="结束时间"),
* @OA\Parameter(name="start_time", in="query", @OA\Schema(type="string"), description="开始时间,例如11:00"),
* @OA\Parameter(name="end_time", in="query", @OA\Schema(type="string"), description="结束时间,例如11:00"),
* @OA\Parameter(name="date", in="query", @OA\Schema(type="string", format="date"), description="日期"),
* @OA\Parameter(name="teacher_id", in="query", @OA\Schema(type="integer"), description="老师ID"),
* @OA\Parameter(name="address", in="query", @OA\Schema(type="string"), description="地址"),

@ -11,6 +11,7 @@ use App\Models\CustomForm;
use App\Models\User;
use App\Notifications\CourseContentNotify;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Validator;

@ -242,9 +242,19 @@ class UserController extends BaseController
$q->where('year', $year);
});
})->count();
// 年度培养学员
$year_training_total = $this->model->whereHas('courseSigns', function ($query) use ($year) {
$query->where('status', 1)->whereHas('course', function ($q) use ($year) {
$q->where('year', $year);
});
})->count();
// 累计培养学员
$training_total = $this->model->whereHas('courseSigns', function ($query) use ($year) {
$query->where('status', 1);
})->count();
$list = $list->paginate($all['page_size'] ?? 20);
}
return $this->success(['list' => $list, 'year_total' => $year_total, 'total' => $total]);
return $this->success(['list' => $list, 'year_total' => $year_total, 'total' => $total, 'year_training_total' => $year_training_total, 'training_total' => $training_total]);
}
/**

@ -450,6 +450,46 @@ class CourseController extends CommonController
return $this->success(compact('list'));
}
/**
* @OA\Get(
* path="/api/mobile/course/distance",
* tags={"小程序-计算距离"},
* summary="签到",
* @OA\Parameter(name="course_content_id", in="query", @OA\Schema(type="string"), required=false, description="课表id"),
* @OA\Parameter(name="longitude", in="query", @OA\Schema(type="string"), required=false, description="longitude"),
* @OA\Parameter(name="latitude", in="query", @OA\Schema(type="string"), required=false, description="latitude"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function distance()
{
$all = \request()->all();
$messages = [
'longitude.required' => '经度必填',
'latitude.required' => '纬度必填',
'course_content_id.required' => '课程id必填',
];
$validator = Validator::make($all, [
'longitude' => 'required',
'latitude' => 'required',
'course_content_id' => 'required'
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
// 获取打卡范围,千米
$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']);
if ($distance > $content_check_range) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '超出打卡范围']);
}
return $this->success('成功');
}
/**
* @OA\Get(
* path="/api/mobile/course/content-check",
@ -487,6 +527,10 @@ class CourseController extends CommonController
if ($distance > $content_check_range) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '超出打卡范围']);
}
// 判断当天才能签到
if (date('Y-m-d') != $courseContent->date) {
return $this->fail([ResponseCode::ERROR_BUSINESS, '不在签到时间']);
}
CourseContentCheck::create([
'course_content_id' => $all['course_content_id'],
'user_id' => $this->getUserId(),

@ -5,10 +5,13 @@
namespace App\Http\Controllers\Mobile;
use App\Helpers\ResponseCode;
use App\Models\AppointmentConfig;
use App\Models\AppointmentType;
use App\Models\Banner;
use App\Models\Config;
use App\Repositories\YuanheRepository;
use Illuminate\Support\Facades\Validator;
class OtherController extends CommonController
{
@ -62,5 +65,36 @@ class OtherController extends CommonController
return $this->success($config);
}
/**
* @OA\Get(
* path="/api/mobile/other/company",
* tags={"小程序-其他"},
* summary="公司搜索",
* @OA\Parameter(name="company_name", in="query", @OA\Schema(type="integer"), required=true, description="公司名字"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function company()
{
$all = \request()->all();
$messages = [
'company_name.required' => '公司名称必填',
];
$validator = Validator::make($all, [
'company_name' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$YuanheRepository = new YuanheRepository();
$result = $YuanheRepository->companyInfo(['enterpriseName' => $all['company_name']]);
if (!$result) {
return $this->fail([ResponseCode::ERROR_PARAMETER, '获取失败']);
}
return $this->success($result);
}
}

@ -17,7 +17,9 @@ use App\Models\ScoreLog;
use App\Models\ThirdAppointmentLog;
use App\Models\User;
use App\Repositories\DoorRepository;
use App\Repositories\YuanheRepository;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
@ -176,6 +178,11 @@ class UserController extends CommonController
}
$model->fill($all);
$model->save();
// 如果有公司信息,就更新一下公司
if (isset($all['company_name']) && !empty($all['company_name'])) {
// 调用命令行更新
Artisan::call("update_company --user_id={$model->id}");
}
// 判断下,如果用户新加入车牌号,并且有未开始或者进行中的预约,则直接预约车牌号
$appointmentModel = Appointment::where('user_id', $this->getUserId())
->where('status', 1)

@ -9,4 +9,41 @@ class Company extends SoftDeletesModel
return $this->hasMany(User::class, 'company_id', 'id');
}
/**
* 地址转经纬度
*/
public static function addressTolocation($address)
{
$map = Config::getValueByKey('map_server');
$map = json_decode($map, true);
$url = "https://restapi.amap.com/v3/geocode/geo";
$params = [
'key' => $map['key'],
'address' => $address,
];
try {
$result = httpCurl($url, 'GET', $params);
$result = json_decode($result, true);
if ($result['status'] == 1) {
$location = $result['geocodes'][0]['location'];
$location = explode(',', $location);
return [
'lng' => $location[0],
'lat' => $location[1],
];
}
return [
'lng' => null,
'lat' => null,
];
} catch (\Exception $e) {
return [
'lng' => null,
'lat' => null,
];
}
}
}

@ -164,6 +164,11 @@ class User extends Authenticatable implements Auditable
return $this->hasMany(Appointment::class, 'user_id', 'id');
}
public function company()
{
return $this->hasOne(Company::class, 'id', 'company_id');
}
/**
* 获取预约剩余次数
*/

@ -3,7 +3,9 @@
namespace App\Repositories;
use App\Models\AppointmentConfig;
use App\Models\Course;
use App\Models\ThirdAppointmentLog;
use App\Models\User;
/**
* 元禾控股
@ -25,11 +27,12 @@ class YuanheRepository
public function getHeader()
{
$timestamp = time();
$token = md5($this->customerId . time() . $this->authKey);
$timestamp = time() * 1000;
$token = $this->customerId . $timestamp . $this->authKey;
$token = md5($token);
$token = strtoupper($token);
$header[] = 'Content-Type: application/x-www-form-urlencoded,application/json';
$header[] = 'Content-Type: application/json';
$header[] = "customerId: {$this->customerId}";
$header[] = "timestamp: {$timestamp}";
$header[] = "token: {$token}";
@ -42,6 +45,7 @@ class YuanheRepository
*/
public function companyInfo($params)
{
$params = json_encode($params);
$url = $this->baseUrl . '/master-service/openapi/businessCollege/enterprise/info';
$header = $this->getHeader();
try {
@ -58,4 +62,37 @@ class YuanheRepository
}
}
/**
* 数据推送
*/
public function pushCourses(Course $course, User $user)
{
if (empty($user->company)) {
return false;
}
$params = [
'classTeacher' => $course->teacher->name,
'courseName' => $course->name,
'description' => $user->company->businessScope,
'enterpriseName' => $user->company->company_name,
'creditCode' => $user->company->credit_code,
'groupId' => '1030004',
'openTime' => $course->start_date
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
$url = $this->baseUrl . '/master-service/openapi/businessCollege/shareInfo/push';
$header = $this->getHeader();
try {
$result = httpCurl($url, 'POST', $params, $header);
$result = json_decode($result, true);
if ($result['code'] == 200) {
return true;
} else {
return false;
}
} catch (\Exception $e) {
return false;
}
}
}

@ -19,9 +19,9 @@ return new class extends Migration
// 纬度
$table->string('latitude')->nullable()->comment('纬度');
// 开始时间
$table->dateTime('start_time')->nullable()->comment('开始时间');
$table->string('start_time')->nullable()->comment('开始时间');
// 结束时间
$table->dateTime('end_time')->nullable()->comment('结束时间');
$table->string('end_time')->nullable()->comment('结束时间');
$table->json('file_ids')->nullable()->comment('文件id数组');
// 详细地址
$table->string('address_detail')->nullable()->comment('详细地址');

@ -46,6 +46,10 @@ return new class extends Migration {
$table->boolean('company_need_fund')->nullable()->comment('公司是否需要融资-0否1是');
// 股东信息
$table->string('company_shareholder')->nullable()->comment('股东信息');
// 经度
$table->string('company_longitude')->nullable()->comment('经度');
// 纬度
$table->string('company_latitude')->nullable()->comment('纬度');
$table->string('company_industry')->nullable()->comment('公司所属行业');
$table->text('company_introduce')->nullable()->comment('公司简介');
@ -55,6 +59,37 @@ return new class extends Migration {
$table->string('sales_volume')->nullable()->comment('销售额');
$table->timestamps();
$table->softDeletes();
// 业务范围
$table->string('business_scope')->nullable()->comment('业务范围');
// 联系邮箱
$table->string('contact_mail')->nullable()->comment('联系邮箱');
// 联系手机
$table->string('contact_phone')->nullable()->comment('联系手机');
// 统一社会代码
$table->string('credit_code')->nullable()->comment('统一社会代码');
// 企业id
$table->string('enterprise_id')->nullable()->comment('企业id');
// 是否境外
$table->tinyInteger('is_abroad')->nullable()->comment('是否境外');
// 是否元禾已投
$table->tinyInteger('is_yh_invested')->nullable()->comment('是否元禾已投');
// 企业logo
$table->string('logo')->nullable()->comment('企业logo');
// 注册金额
$table->string('regist_amount')->nullable()->comment('注册金额');
// 注册资本币种
$table->string('regist_capi_type')->nullable()->comment('注册资本币种');
// 企业状态
$table->string('status')->nullable()->comment('企业状态');
// 上市日期
$table->string('stock_date')->nullable()->comment('上市日期');
// 股票代码
$table->string('stock_number')->nullable()->comment('股票代码');
// 上市类型
$table->string('stock_type')->nullable()->comment('上市类型');
// 注册资本币种
$table->string('currency_type')->nullable()->comment('注册资本币种');
});
}

@ -4,8 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
return new class extends Migration {
/**
* Run the migrations.
*
@ -16,6 +15,8 @@ return new class extends Migration
Schema::table('course_types', function (Blueprint $table) {
// 是否参与统计
$table->boolean('is_chart')->default(true)->comment('是否参与统计0否1是');
// 是否推送
$table->boolean('is_push')->default(false)->comment('是否推送0否1是');
});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -238,6 +238,8 @@ Route::group(["namespace" => "Mobile", "prefix" => "mobile"], function () {
Route::get('other/config', [\App\Http\Controllers\Mobile\OtherController::class, "config"]);
// 轮播图
Route::get('other/banner', [\App\Http\Controllers\Mobile\OtherController::class, "banner"]);
// 公司查询
Route::get('other/company', [\App\Http\Controllers\Mobile\OtherController::class, "company"]);
// 通知
Route::get('course/notices', [\App\Http\Controllers\Mobile\CourseController::class, "notices"]);
// 课程
@ -277,6 +279,8 @@ Route::group(["namespace" => "Mobile", "prefix" => "mobile"], function () {
Route::get('course/pay', [\App\Http\Controllers\Mobile\CourseController::class, "pay"]);
Route::get('course/contents', [\App\Http\Controllers\Mobile\CourseController::class, "contents"]);
// 计算距离
Route::get('course/distance', [\App\Http\Controllers\Mobile\CourseController::class, "distance"]);
// 签到
Route::get('course/content-check', [\App\Http\Controllers\Mobile\CourseController::class, "contentCheck"]);
// 签到列表

Loading…
Cancel
Save