642 lines
31 KiB
PHP
642 lines
31 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Models\CityGps;
|
||
use App\Models\Profile;
|
||
use App\Utils\Common;
|
||
use Calchen\LaravelDingtalkRobot\DingtalkRobot;
|
||
use Calchen\LaravelDingtalkRobot\Message\TextMessage;
|
||
use Exception;
|
||
use Illuminate\Support\Facades\Redis;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Throwable;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Overtrue\Pinyin\Pinyin;
|
||
use App\Utils\Http;
|
||
|
||
class SaasMatchService
|
||
{
|
||
//偏好要求字段
|
||
const prefer_attrs = [
|
||
'min_age', 'max_age', 'min_height', 'max_height', 'is_same_city', 'is_same_resident_province'
|
||
];
|
||
|
||
const degree = [
|
||
'其他' => 0, '小学' => 1, '初中' => 2, '初中及初中以下' => 2, '中专' => 4, '高中' => 4,
|
||
'高中/中专' => 4, '大专' => 5, '专科' => 5, '本科' => 6, '硕士' => 7, '硕士以上' => 7,'博士' => 8,
|
||
];
|
||
|
||
function __construct()
|
||
{
|
||
// Log::notice('[CommonService] init global common services');
|
||
}
|
||
|
||
|
||
/**
|
||
* 字符串截取指定长度
|
||
* @param $text
|
||
* @param $length
|
||
* @param string $replace
|
||
* @param string $encoding
|
||
* @return string
|
||
*/
|
||
static public function substring_format($text, $length, $replace = '......', $encoding = 'UTF-8')
|
||
{
|
||
if ($text && mb_strlen($text, $encoding) > $length) {
|
||
return mb_substr($text, 0, $length, $encoding) . $replace;
|
||
}
|
||
return $text;
|
||
}
|
||
|
||
/**
|
||
* 计算两个用户的分值
|
||
* 将send_user_id 推给 user_id
|
||
* @param $user_id
|
||
* @param $send_user_id
|
||
* @param bool $is_full
|
||
* @return bool|mixed
|
||
* @throws \Calchen\LaravelDingtalkRobot\Exceptions\Exception
|
||
*/
|
||
public function calculateUserScore($user, $send_user)
|
||
{
|
||
//$match['userId'] = $user->user_id;
|
||
//$match['sendUserId'] = $send_user->user_id;
|
||
/** 计算年龄 */
|
||
$match['age'] = $this->calculateAge($user, $send_user);
|
||
/** 计算身高 */
|
||
$match['stature'] = $this->calculateStature($user, $send_user);
|
||
/** 计算信仰 */
|
||
$match['belief'] = $this->calculateBelief($user, $send_user);
|
||
/** 计算最低月收入 */
|
||
$match['salary'] = $this->calculateSalary($user, $send_user);
|
||
/** 计算学历 */
|
||
$match['degree'] = $this->calculateDegreeScore($user, $send_user);
|
||
/** 计算地域 */
|
||
$match['regional'] = $this->calculateRegional($user, $send_user);
|
||
$match['total_score'] = $match['age']['分值'] + $match['stature']['分值']
|
||
+ $match['belief']['分值'] + $match['degree']['分值'] + $match['regional']['分值'];
|
||
return $match;
|
||
}
|
||
|
||
/**
|
||
* 计算年龄分数
|
||
* @param $user
|
||
* @param $send_user
|
||
* @return array
|
||
* @throws \Calchen\LaravelDingtalkRobot\Exceptions\Exception
|
||
*/
|
||
public function calculateAge($user, $send_user): array
|
||
{
|
||
|
||
$score = 10;
|
||
$send_user_age = $this->getAge($send_user->birthday);
|
||
if ($send_user_age < 18) {
|
||
return ['code' => 1, '期望年龄' => '', '实际年龄' => $send_user_age, '分值' => 0];
|
||
}
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
if ($mate_conditon && $mate_conditon['age'] != '年龄不限') {
|
||
list($min_age, $max_age) = explode("-", $mate_conditon['age']);
|
||
$max_age = str_replace('岁', "", $max_age);
|
||
//是否要求
|
||
if ($min_age && $max_age) { //有要求
|
||
if ($send_user_age < $min_age) {
|
||
$subAge = $min_age - $send_user_age;
|
||
$score = $score + $subAge;
|
||
if ($score > 10) {
|
||
$score = 10;
|
||
}
|
||
return ['code' => 0, '期望年龄' => $min_age . '-' . $max_age . '之间,', '实际年龄' => $send_user_age, '分值' => $score];
|
||
} elseif ($send_user_age > $max_age) {
|
||
$subAge = $send_user_age - $max_age;
|
||
$score = $score - $subAge;
|
||
if ($score < 0) {
|
||
$score = 0;
|
||
}
|
||
return ['code' => 0, '期望年龄' => $min_age . '-' . $max_age . '之间,', '实际年龄' => $send_user_age, '分值' => $score];
|
||
} elseif ($send_user_age > $min_age && $send_user_age < $max_age) {
|
||
return ['code' => 0, '期望年龄' => $min_age . '-' . $max_age . '之间,', '实际年龄' => $send_user_age, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望年龄' => $min_age . '-' . $max_age . '之间,', '实际年龄' => $send_user_age, '分值' => $score];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '期望年龄' => $mate_conditon['age'], '实际年龄' => $send_user_age, '分值' => $score];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '期望年龄' => '无要求', '实际年龄' => $send_user_age, '分值' => $score];
|
||
}
|
||
|
||
}
|
||
|
||
/**
|
||
* 获取年龄
|
||
* @param string $birthday 生日
|
||
* @return integer 年龄
|
||
*/
|
||
public function getAge($birthday): int
|
||
{
|
||
if (empty($birthday)) {
|
||
return 0;
|
||
}
|
||
$age = strtotime($birthday);
|
||
if ($age === false) {
|
||
return 0;
|
||
}
|
||
list($y1, $m1, $d1) = explode("-", date("Y-m-d", $age));
|
||
$now = strtotime("now");
|
||
list($y2, $m2, $d2) = explode("-", date("Y-m-d", $now));
|
||
$age = $y2 - $y1;
|
||
if ((int)($m2 . $d2) < (int)($m1 . $d1))
|
||
$age -= 1;
|
||
return $age;
|
||
}
|
||
|
||
/**
|
||
* 计算身高分数
|
||
* @param $user
|
||
* @param $send_user
|
||
* @return array
|
||
* @throws \Calchen\LaravelDingtalkRobot\Exceptions\Exception
|
||
*/
|
||
public function calculateStature($user, $send_user): array
|
||
{
|
||
$score = 10;
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
if ($mate_conditon && $mate_conditon['stature'] != '身高不限') {
|
||
list($min_height, $max_height) = explode("-", $mate_conditon['stature']);
|
||
$max_height = str_replace('cm', "", $max_height);
|
||
if(empty($max_height)){
|
||
$max_height = 190;
|
||
}
|
||
if (isset($min_height) || isset($max_height)) {
|
||
if ($send_user->stature < $min_height) {
|
||
$subStature = $min_height - $send_user->stature;
|
||
$score = $score - $subStature;
|
||
if ($score < 0) {
|
||
$score = 0;
|
||
}
|
||
return ['code' => 0, '期望身高' => $min_height . '-' . $max_height . '之间,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
} elseif ($send_user->stature > $max_height) {
|
||
$subStature = $send_user->stature - $max_height;
|
||
$score = $score + $subStature;
|
||
if ($score > 10) {
|
||
$score = 10;
|
||
}
|
||
return ['code' => 0, '期望身高' => $min_height . '-' . $max_height . '之间,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
} elseif ($send_user->stature > $min_height && $send_user->stature < $max_height) {
|
||
return ['code' => 0, '期望身高' => $min_height . '-' . $max_height . '之间,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望身高' => $min_height . '-' . $max_height . '之间,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '期望身高' => '无要求,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
}
|
||
} else {
|
||
if ($send_user->stature) {
|
||
return ['code' => 0, '期望身高' => '无要求,', '实际身高' => $send_user->stature, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望身高' => '无要求,', '实际身高' => "未填写", '分值' => $score];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 计算信仰分数
|
||
* @param $user
|
||
* @param $send_user
|
||
* @throws \Calchen\LaravelDingtalkRobot\Exceptions\Exception
|
||
*/
|
||
public function calculateBelief($user, $send_user): array
|
||
{
|
||
|
||
$score = 10;
|
||
if ($user->mate_conditon) {
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
//有要求信仰
|
||
if ($mate_conditon && $mate_conditon['belief'] != '信仰不限') {
|
||
//同信仰
|
||
if ($mate_conditon['belief'] == $send_user->belief) {
|
||
return ['code' => 0, '要求信仰' => $mate_conditon['belief'], '用户信仰' => $send_user->belief, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '要求信仰' => $mate_conditon['belief'], '用户信仰' => $send_user->belief, '分值' => 0];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '要求信仰' => '未要求', '用户信仰' => $send_user->belief, '分值' => $score];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '要求信仰' => '未要求', '用户信仰' => $send_user->belief, '分值' => $score];
|
||
}
|
||
|
||
|
||
}
|
||
|
||
/**
|
||
* 计算月收入
|
||
* @param $user
|
||
* @param $send_user
|
||
*/
|
||
public function calculateSalary($user, $send_user): array
|
||
{
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
$score = 10;
|
||
if (isset($mate_conditon['income']) && $mate_conditon['income'] != '月收入不限') {
|
||
if (strpos($mate_conditon['income'], '-')) {
|
||
list($min_salary, $max_salary) = explode("-", $mate_conditon['income']);
|
||
if (strpos($min_salary, '千')) {
|
||
$min_salary = str_replace('千', "", $min_salary);
|
||
$min_salary = $min_salary * 12;
|
||
|
||
}
|
||
if (strpos($max_salary, '千')) {
|
||
$max_salary = str_replace('千', "", $max_salary);
|
||
$max_salary = $max_salary * 12;
|
||
}
|
||
if (strpos($min_salary, '万')) {
|
||
$min_salary = str_replace('万', "", $min_salary);
|
||
$min_salary = $min_salary * 10 * 12;
|
||
}
|
||
|
||
if (strpos($max_salary, '万')) {
|
||
$max_salary = str_replace('万', "", $max_salary);
|
||
$max_salary = $max_salary * 10 * 12;
|
||
}
|
||
} elseif (strpos($mate_conditon['income'], '以上')) {
|
||
$min_salary = str_replace('万以上', "", $mate_conditon['income']);
|
||
$min_salary = $min_salary * 10 * 12;
|
||
$max_salary = $min_salary;
|
||
}
|
||
|
||
if ($send_user->income) {
|
||
if (strpos($send_user->income, '~')) {
|
||
list($send_user_min_salary, $send_user_max_salary) = explode('~', $send_user->income);
|
||
$send_user_max_salary = str_replace("w", "", $send_user_max_salary);
|
||
$send_user_salary = ($send_user_min_salary + $send_user_max_salary) / 2 * 10;
|
||
if ($min_salary > $send_user_salary) {
|
||
$sub_salary = $min_salary - $send_user_salary;
|
||
$score = $score - $sub_salary;
|
||
if ($score < 0) {
|
||
$score = 0;
|
||
}
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪平均数' => $send_user_salary . '千', '分值' => $score];
|
||
} elseif ($max_salary < $send_user_salary) {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪平均数' => $send_user_salary . '千', '分值' => $score];
|
||
} elseif ($min_salary < $send_user_salary && $max_salary > $send_user_salary) {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪平均数' => $send_user_salary . '千', '分值' => $score];
|
||
}
|
||
} elseif (strpos($send_user->income, '以下')) {
|
||
$send_user_max_salary = str_replace("w以下", "", $send_user->income);
|
||
$send_user_max_salary = $send_user_max_salary * 10;
|
||
if ($min_salary > $send_user_max_salary) {
|
||
$sub_salary = $min_salary - $send_user_max_salary;
|
||
$score = $score - $sub_salary;
|
||
if ($score < 0) {
|
||
$score = 0;
|
||
}
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_max_salary . '千以下', '分值' => $score];
|
||
} elseif ($send_user_max_salary > $max_salary) {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_max_salary . '千以下', '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_max_salary . '千以下', '分值' => $score];
|
||
}
|
||
|
||
} elseif (strpos($send_user->income, '以上')) {
|
||
$send_user_min_salary = str_replace("w以上", "", $send_user->income);
|
||
$send_user_min_salary = $send_user_min_salary * 10;
|
||
if ($min_salary > $send_user_min_salary) {
|
||
$sub_salary = $min_salary - $send_user_min_salary;
|
||
$score = $score - $sub_salary;
|
||
if ($score < 0) {
|
||
$score = 0;
|
||
}
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_min_salary . '千以上', '分值' => $score];
|
||
} elseif ($send_user_min_salary > $max_salary) {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_min_salary . '千以上', '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪' => $send_user_min_salary . '千以上', '分值' => $score];
|
||
}
|
||
}
|
||
} else {
|
||
return ['code' => 0, '期望年薪' => $min_salary . '-' . $max_salary . '千', '实际年薪平均数' => "未设置", '分值' => 0];
|
||
}
|
||
} else {
|
||
if ($send_user->income) {
|
||
return ['code' => 0, '期望年薪' => "未设置", '实际年薪平均数' => $send_user->income, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '期望年薪' => "未设置", '实际年薪平均数' => "未设置", '分值' => $score];
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 计算动态学历分数
|
||
* @param $user
|
||
* @param $send_user
|
||
* @return array
|
||
*/
|
||
public function calculateDegreeScore($user, $send_user)
|
||
{
|
||
$score = 10;
|
||
if ($user->mate_conditon) {
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
if ($mate_conditon['degree'] != '学历不限') {
|
||
if (!$send_user->degree) {
|
||
return ['code' => 0, '要求学历' => $mate_conditon['degree'], '用户学历' => "未设置", '分值' => 0];
|
||
} else {
|
||
//学历文字转为数字以备比较
|
||
$user_degree_number = self::degree[$mate_conditon['degree']];
|
||
$send_user_degree_number = self::degree[$send_user->degree];
|
||
if ($send_user_degree_number < $user_degree_number) {
|
||
$sub_degree = $user_degree_number - $send_user_degree_number;
|
||
$score = $score - $sub_degree;
|
||
return ['code' => 0, '要求学历' => $mate_conditon['degree'], '用户学历' => $send_user->degree, '分值' => $score];
|
||
} elseif ($send_user_degree_number > $user_degree_number) {
|
||
return ['code' => 0, '要求学历' => $mate_conditon['degree'], '用户学历' => $send_user->degree, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '要求学历' => $mate_conditon['degree'], '用户学历' => $send_user->degree, '分值' => $score];
|
||
}
|
||
}
|
||
} else {
|
||
return ['code' => 0, '要求学历' => '未设置', '用户学历' => $send_user->degree, '分值' => $score];
|
||
}
|
||
} else {
|
||
return ['code' => 0, '要求学历' => '未设置', '用户学历' => $send_user->degree, '分值' => $score];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 计算地域分数
|
||
* @param $user
|
||
* @param $send_user
|
||
* @return array
|
||
*/
|
||
public function calculateRegional($user, $send_user): array
|
||
{
|
||
$score = 10;
|
||
if ($user->mate_conditon) {
|
||
$mate_conditon = json_decode($user->mate_conditon, true);
|
||
if ($mate_conditon['location'] == '所在地不限') {
|
||
return ['code' => 0, '要求所在地' => '所在地不限', '用户所在地' => $send_user->city, '分值' => $score];
|
||
} elseif ($mate_conditon['location'] == '距离优先') {
|
||
if (($user->province != $send_user->province || empty($send_user->province)) && ($user->resident_province != $send_user->resident_province || empty($send_user->resident_province))) {
|
||
//非同省同家乡 或者 没有地址信息
|
||
$score = 0;
|
||
} elseif (($user->province != $send_user->province || empty($send_user->province)) && ($user->resident_province == $send_user->resident_province && $user->resident_city != $send_user->resident_city)) {
|
||
//非同省、同家乡省、非同家乡市
|
||
$score += $user->type == "single" ? 1 : 10;
|
||
} elseif (($user->province != $send_user->province || empty($send_user->province)) && $user->resident_city == $send_user->resident_city) {
|
||
//非同省、同家乡省市
|
||
$score += $user->type == "single" ? 2 : 20;
|
||
} elseif (($user->province == $send_user->province && $user->city != $send_user->city) && ($user->resident_province != $send_user->resident_province || empty($send_user->resident_province))) {
|
||
//同省非同市、非同家乡省
|
||
$score += $user->type == "single" ? 3 : 30;
|
||
} elseif (($user->province == $send_user->province && $user->city != $send_user->city) && ($user->resident_province == $send_user->resident_province && $user->resident_city != $send_user->resident_city)) {
|
||
//同省非同市、同家乡省非同家乡市
|
||
$score += $user->type == "single" ? 3 : 30;
|
||
} elseif (($user->province == $send_user->province && $user->city != $send_user->city) && $user->resident_city == $send_user->resident_city) {
|
||
//同省非同市、同家乡市
|
||
$score += $user->type == "single" ? 4 : 40;
|
||
} elseif ($user->city != $send_user->city && $user->resident_province != $send_user->resident_province) {
|
||
//同市、同家乡省
|
||
$score += $user->type == "single" ? 4 : 40;
|
||
} elseif (($user->province == $send_user->province && $user->city != $send_user->city) && $user->resident_city == $send_user->resident_city) {
|
||
//同省非同市、同家乡市
|
||
$score += $user->type == "single" ? 5 : 50;
|
||
} elseif ($user->city == $send_user->city && $user->resident_city == $send_user->resident_city) {
|
||
//同省非同市、同家乡市
|
||
$score += $user->type == "single" ? 6 : 60;
|
||
}
|
||
return ['code' => 0, '要求' => '距离优先', '用户所在地' => $user->province, '分值' => $score];
|
||
} else {
|
||
if ($mate_conditon['location'] == $user->province) {
|
||
return ['code' => 0, '要求所在地' => $mate_conditon['location'], '用户所在地' => $user->province, '分值' => $score];
|
||
} else {
|
||
return ['code' => 0, '要求所在地' => $mate_conditon['location'], '用户所在地' => $user->province, '分值' => 0];
|
||
}
|
||
}
|
||
} else {
|
||
return ['code' => 0, '要求所在地' => '未要求', '用户所在地' => $user->province, '分值' => 10];
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检测单身状态
|
||
* @param $user
|
||
* @param $send_user
|
||
* @return array
|
||
* @throws \Calchen\LaravelDingtalkRobot\Exceptions\Exception
|
||
*/
|
||
public function checkType($user, $send_user): array
|
||
{
|
||
|
||
if (empty($user->type) || empty($user->sex) || empty($send_user->sex) || empty($send_user->type)) {
|
||
return ['code' => 1, 'msg' => 'user_id = ' . $user->id . ', send_user_id =' . $send_user->id . " 有性别信息或者没有用户类型,"];
|
||
}
|
||
//类型不同
|
||
if ($user->type != $send_user->type) {
|
||
//单身
|
||
if ($user->type == 'signle') {
|
||
return ['code' => 1, 'msg' => 'receive_user_id = ' . $user->id . ',send_user_id = ' . $send_user->id . " 介绍人不能匹配给单身,"];
|
||
}
|
||
} else {
|
||
//介绍人
|
||
if ($send_user->type != 'single') {
|
||
return ['code' => 1, 'msg' => 'receive_user_id = ' . $user->id . ',send_user_id = ' . $send_user->id . " 介绍人之间不能相互匹配,"];
|
||
}
|
||
}
|
||
return ['code' => 0, 'msg' => ''];
|
||
|
||
}
|
||
|
||
/**
|
||
* 查询城市gps
|
||
* @param $city_pin_yin
|
||
* @param $user
|
||
* @param $city
|
||
* @return array|false|mixed
|
||
*/
|
||
public function getCityGps($city_pin_yin, $user, $city)
|
||
{
|
||
if (isset(self::$static_city_gps[$city_pin_yin])) {
|
||
$city_gps = self::$static_city_gps[$city_pin_yin];
|
||
} else {
|
||
$city_gps = json_decode(Redis::get('cityGps:' . $city_pin_yin), true);
|
||
if (empty($city_gps)) {
|
||
//Log::warning('[calculateRegional] 从数据据查询城市!!!');
|
||
$city_gps = CityGps::where('prefecture_level_city', $city)->select('prefecture_level_city', 'east_longitude', 'northern_latitude')->first();
|
||
if (!empty($city_gps)) {
|
||
Redis::set('cityGps:' . $city_pin_yin, json_encode($city_gps));
|
||
self::$static_ai_reviews[$city_pin_yin] = $city_gps;
|
||
} else {
|
||
Log::warning('[calculateRegional] 百度查询!!!');
|
||
$request_url = 'http://api.map.baidu.com/geocoder?';
|
||
$request_address = 'address=地址';
|
||
$request_output = '&output=json';
|
||
$request_key = '&key=nKGpPpuOlcOA3nPy9jHj28kywEkn1N08';
|
||
$request_city = '&city=' . $user->city;
|
||
$url = $request_url . $request_address . $request_output . $request_key . $request_city;
|
||
$result = Http::post($url, null);
|
||
if (!empty($result)) {
|
||
$result = json_decode($result, true);
|
||
if ($result['status'] == 'OK' && !empty($result['result']['location']['lng']) && !empty($result['result']['location']['lat'])) {
|
||
if ($result['result']['location']['lng'] == '104.102' || $result['result']['location']['lat'] == '30.6545') {
|
||
Log::warning('查询用户城市位置出错了!!! user_id = ' . $user->id . ' city = ' . $user->city);
|
||
return ['code' => 1, 'msg' => '查询用户城市位置出错了!!! user_id = ' . $user->id . ' city = ' . $user->city . ','];
|
||
}
|
||
$insert = [
|
||
'east_longitude' => $result['result']['location']['lng'],
|
||
'northern_latitude' => $result['result']['location']['lat'],
|
||
'area_code' => '999999',
|
||
'province' => str_replace('省', '', $user->province),
|
||
'prefecture_level_city' => str_replace('市', '', $user->city),
|
||
'county_level_city' => str_replace('市', '', $user->city),
|
||
'ping_yin' => $city,
|
||
//'ping_yin' =>str_replace( '-','',$pinyin->permalink($city)),
|
||
'telephone_area_code' => '999999',
|
||
'postal_code' => '999999',
|
||
];
|
||
CityGps::insert($insert);
|
||
Redis::set('cityGps:' . $city_pin_yin, json_encode($insert));
|
||
$city_gps = $insert;
|
||
self::$static_city_gps[$city_pin_yin] = $insert;
|
||
} else {
|
||
Log::warning('查不到用户城市位置 user_id = ' . $user->id . ' city = ' . $user->city);
|
||
return ['code' => 1, 'msg' => '查不到用户城市位置 user_id = ' . $user->id . ' city = ' . $user->city . ','];
|
||
}
|
||
} else {
|
||
return ['code' => 1, 'msg' => '查不到用户城市位置 user_id = ' . $user->id . ' city = ' . $user->city . ','];
|
||
}
|
||
}
|
||
} else {
|
||
self::$static_city_gps[$city_pin_yin] = $city_gps;
|
||
}
|
||
}
|
||
$city_gps['code'] = 0;
|
||
return $city_gps;
|
||
}
|
||
|
||
/**
|
||
* 查询其它城市是否在范围内
|
||
* @param $city_pin_yin
|
||
* @param $city_gps
|
||
* @return array
|
||
*/
|
||
public function getOtherCity($city_pin_yin, $city_gps)
|
||
{
|
||
if (isset(self::$static_other_city[$city_pin_yin])) {
|
||
$other_city = self::$static_other_city[$city_pin_yin];
|
||
} else {
|
||
$other_city = json_decode(Redis::get('otherCity:' . $city_pin_yin));
|
||
if (empty($other_city)) {
|
||
$point = $this->returnSquarePoint($city_gps['east_longitude'], $city_gps['northern_latitude'], 300);
|
||
$other_city = CityGps::where('northern_latitude', '>', $point['right_bottom']['lat'])->where('northern_latitude', '<', $point['left_top']['lat'])
|
||
->where('east_longitude', '>', $point['left_top']['lng'])->where('east_longitude', '<', $point['right_bottom']['lng'])
|
||
->pluck('prefecture_level_city')->toArray();
|
||
if (!empty($other_city)) {
|
||
$other_city = array_unique($other_city);
|
||
Redis::set("otherCity:" . $city_pin_yin, json_encode(array_values($other_city)));
|
||
self::$static_other_city[$city_pin_yin] = $other_city;
|
||
} else {
|
||
return ['code' => 1, 'msg' => '城市不在范围内,'];
|
||
}
|
||
} else {
|
||
if (!is_array($other_city)) {
|
||
$other_city = json_decode($other_city, true);
|
||
}
|
||
self::$static_other_city[$city_pin_yin] = $other_city;
|
||
}
|
||
}
|
||
$other_city['code'] = 0;
|
||
return $other_city;
|
||
}
|
||
|
||
/**
|
||
*计算某个经纬度的周围某段距离的正方形的四个点
|
||
* @param $lng
|
||
* @param $lat
|
||
* @param float $distance
|
||
* @return array 正方形的四个点的经纬度坐标
|
||
*/
|
||
function returnSquarePoint($lng, $lat, $distance = 0.5)
|
||
{
|
||
$EARTH_RADIUS = 6371;//地球半径,平均半径为6371km
|
||
$dlng = 2 * asin(sin($distance / (2 * $EARTH_RADIUS)) / cos(deg2rad($lat)));
|
||
$dlng = rad2deg($dlng);
|
||
$dlat = $distance / $EARTH_RADIUS;
|
||
$dlat = rad2deg($dlat);
|
||
return array(
|
||
'left_top' => array('lat' => round($lat + $dlat, 2), 'lng' => round($lng - $dlng, 2)),
|
||
'right_top' => array('lat' => round($lat + $dlat, 2), 'lng' => round($lng + $dlng, 2)),
|
||
'left_bottom' => array('lat' => round($lat - $dlat, 2), 'lng' => round($lng - $dlng, 2)),
|
||
'right_bottom' => array('lat' => round($lat - $dlat, 2), 'lng' => round($lng + $dlng, 2))
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 计算两个坐标的距离
|
||
* @param $lng1 , $lng2 经度
|
||
* @param $lat1 , $lat2 纬度
|
||
* @param int $unit 单位 1:米 2:千米
|
||
* @param int $decimal 精度 保留小数位数
|
||
*/
|
||
function getDistance($lng1, $lat1, $lng2, $lat2, $unit = 1, $decimal = 2)
|
||
{
|
||
$earthdata = 6371;//地球半径,平均半径为6371km
|
||
// 将角度转为狐度
|
||
$radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
|
||
$radLat2 = deg2rad($lat2);
|
||
$radLng1 = deg2rad($lng1);
|
||
$radLng2 = deg2rad($lng2);
|
||
$dlat = $radLat1 - $radLat2;
|
||
$dlng = $radLng1 - $radLng2;
|
||
$length = 2 * asin(sqrt(pow(sin($dlat / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($dlng / 2), 2))) * $earthdata * 1000;
|
||
|
||
if ($unit == 2) {
|
||
$length /= 1000;
|
||
}
|
||
$length = round($length, $decimal);
|
||
return $length;
|
||
}
|
||
|
||
/**
|
||
* 年龄转成时间
|
||
* @param $age
|
||
* @param string $symbol
|
||
* @return string
|
||
*/
|
||
public function ageToBirthday($age, $symbol = '-')
|
||
{
|
||
$age = $age == 0 ? 25 : $age;
|
||
$nowyear = date("Y", time());
|
||
$year = $nowyear - $age;
|
||
$monthArr = [];
|
||
for ($i = 1; $i < 13; $i++) {
|
||
$monthArr[] = $i < 10 ? '0' . $i : $i;
|
||
}
|
||
$dayArr = [];
|
||
for ($i = 1; $i < 29; $i++) {
|
||
$dayArr[] = $i < 10 ? '0' . $i : $i;
|
||
}
|
||
$month_key = array_rand($monthArr, 1);
|
||
$month = $monthArr[$month_key];
|
||
$date_tmp_stamp = strtotime($year . '-' . $month);
|
||
$day = '';
|
||
if ($month == '02' && date("t", $date_tmp_stamp) == '29') {
|
||
$dayArr = array_merge($dayArr, ['29']);
|
||
$day_key = array_rand($dayArr, 1);
|
||
$day = $dayArr[$day_key];
|
||
} else if ($month == '02' && date("t", $date_tmp_stamp) == '28') {
|
||
$day_key = array_rand($dayArr, 1);
|
||
$day = $dayArr[$day_key];
|
||
} else if (in_array($month, ['01', '03', '05', '07', '08', '10', '12'])) {
|
||
$dayArr = array_merge($dayArr, ['29', '30', '31']);
|
||
$day_key = array_rand($dayArr, 1);
|
||
$day = $dayArr[$day_key];
|
||
} else {
|
||
$dayArr = array_merge($dayArr, ['29', '30']);
|
||
$day_key = array_rand($dayArr, 1);
|
||
$day = $dayArr[$day_key];
|
||
}
|
||
return $year . $symbol . $month . $symbol . $day;
|
||
}
|
||
}
|