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

master
lion 4 months ago
commit 28cfc62955

@ -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,8 +2,10 @@
namespace App\Console\Commands;
use App\Models\Company;
use App\Models\User;
use App\Repositories\MeetRepository;
use App\Repositories\YuanheRepository;
use Illuminate\Console\Command;
@ -14,7 +16,7 @@ class UpdateCompany extends Command
*
* @var string
*/
protected $signature = 'update_company';
protected $signature = 'update_company {--user_id=}';
/**
* The console command description.
@ -40,10 +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('全部更新完成');
}
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]);
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('公司信息-全部更新完成');
}
/**
* 更新经纬度信息
*/
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');
}
/**
* 获取预约剩余次数
*/

@ -0,0 +1,97 @@
<?php
namespace App\Repositories;
use App\Models\AppointmentConfig;
use App\Models\Course;
use App\Models\ThirdAppointmentLog;
use App\Models\User;
/**
* 元禾控股
*/
class YuanheRepository
{
public $baseUrl;
public $customerId;
public $authKey;
public function __construct()
{
// 测试地址
$this->baseUrl = 'https://uat.oriza.com';
$this->customerId = '1947941625517604864';
$this->authKey = '59C8ED8584EE4BA7BC22FC63BE45C73D';
}
public function getHeader()
{
$timestamp = time() * 1000;
$token = $this->customerId . $timestamp . $this->authKey;
$token = md5($token);
$token = strtoupper($token);
$header[] = 'Content-Type: application/json';
$header[] = "customerId: {$this->customerId}";
$header[] = "timestamp: {$timestamp}";
$header[] = "token: {$token}";
return $header;
}
/**
* 公司查询
*/
public function companyInfo($params)
{
$params = json_encode($params);
$url = $this->baseUrl . '/master-service/openapi/businessCollege/enterprise/info';
$header = $this->getHeader();
try {
$result = httpCurl($url, 'POST', $params, $header);
$result = json_decode($result, true);
if ($result['code'] == 200) {
return $result['data'];
} else {
return false;
}
} catch (\Exception $e) {
return false;
}
}
/**
* 数据推送
*/
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是');
});
}

@ -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