From c5429ca5bc99369f73526823a68e36223a7190f5 Mon Sep 17 00:00:00 2001 From: zwesy Date: Thu, 25 Nov 2021 18:54:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9A=E6=B6=88?= =?UTF-8?q?=E8=B4=B9=E8=80=85=E6=9F=A5=E7=9C=8B=E5=95=86=E5=AE=B6=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E7=9A=84=E4=BC=98=E6=83=A0=E5=8D=B7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common.php | 83 ++++++++++++++++++++++++++ app/controller/api/Business.php | 13 +++++ app/controller/api/Consumer.php | 91 +++++++++++++++++++++++++++++ app/controller/api/User.php | 5 ++ app/repository/CouponRepository.php | 18 ++++++ 5 files changed, 210 insertions(+) create mode 100644 app/controller/api/Business.php create mode 100644 app/controller/api/Consumer.php diff --git a/app/common.php b/app/common.php index ef23365..a8455c0 100644 --- a/app/common.php +++ b/app/common.php @@ -683,4 +683,87 @@ if (!function_exists('generateDefaultNickName')) { { return '用户'.generateRand('6', 'mix'); } +} + +/** + * 根据当前坐标和范围距离计算方形范围内的经纬度坐标取值范围 + * $curLat double类型 当前坐标纬度 + * $curLng double类型 当前坐标经度 + * $distance double类型 查询范围(单位km),当前坐标所在园的半径,与此范围正方形内切 + * + * 相关数学知识:半正矢公式(Haversine公式)、正/反弦函数和正/反切函数等三角函数 + * 平均地球半径:6371km + * 经度范围:-180 ~ 180 (注意差值180度限制时的计算) + * 纬度范围:-90 ~ 90 + * + */ +if (!function_exists('getEarthSquareRangePoint')) { + function getEarthSquareRangePoint($curLat, $curLng, $distance) + { + $list = []; + $earthRadius = 6371; // 地球平均半径 6371km + $disLat = rad2deg($distance / $earthRadius); + $disLng = rad2deg(2 * asin(sin($distance / (2 * $earthRadius) / cos(deg2rad($curLat))))); + $disLat = abs($disLat); + $disLng = abs($disLng); + + $list['cur_lat'] = $curLat; + $list['cur_lng'] = $curLng; + $list['dis_lat'] = $disLat; + $list['dis_lng'] = $disLng; + + $latTop = $curLat + $disLat; + $latBottom = $curLat - $disLat; + $lngLeft = $curLng - $disLng; + $lngRight = $curLng + $disLng; + + + $checkLatTopRem = abs(fmod(floatval($latTop), 180)); + $checkLatTop = abs(fmod(intval($latTop / 90), 4)); + if ($latTop >= 0) { + $latTop = floatval($checkLatTopRem > 90 ? (180 - $checkLatTopRem) : $checkLatTopRem); + $latTop = $checkLatTop >= 2 ? (-$latTop) : $latTop; // 南半球为负数 + } else { + $latTop = floatval($checkLatTopRem > 90 ? (180 - $checkLatTopRem) : $checkLatTopRem); + $latTop = $checkLatTop < 2 ? (-$latTop) : $latTop; // 南半球为负数 + } + + $checkLatBottomRem = abs(fmod(floatval($latBottom) ,180)); + $checkLatBottom = abs(intval($latBottom / 90) % 4); + if ($latBottom >= 0) { + $latBottom = floatval($checkLatBottomRem > 90 ? (180 - $checkLatBottomRem) : $checkLatBottomRem); + $latBottom = $checkLatBottom >= 2 ? (-$latBottom) : $latBottom; // 南半球为负数 + } else { + $latBottom = floatval($checkLatBottomRem > 90 ? (180 - $checkLatBottomRem) : $checkLatBottomRem); + $latBottom = $checkLatBottom < 2 ? (-$latBottom) : $latBottom; // 南半球为负数 + } + + $list['lat_min'] = min([$latTop, $curLat, $latBottom]); + $list['lat_max'] = max([$latTop, $curLat, $latBottom]); + + + $checkLngLeftRem = abs(fmod(floatval($lngLeft), 360)); + if ($lngLeft >= 0) { + $lngLeft = floatval($checkLngLeftRem > 180 ? -(360 - $checkLngLeftRem) : $checkLngLeftRem); // 西半球为负数 + } else { + $lngLeft = floatval($checkLngLeftRem > 180 ? (360 - $checkLngLeftRem) : (-$checkLngLeftRem)); // 西半球为负数 + } + + $checkLngRightRem = abs(fmod(floatval($lngRight), 360)); + if ($lngRight >= 0) { + $lngRight = floatval($checkLngRightRem > 180 ? -(360 - $checkLngRightRem) : $checkLngRightRem); // 西半球为负数 + } else { + $lngRight = floatval($checkLngRightRem > 180 ? (360 - $checkLngRightRem) : (-$checkLngRightRem)); // 西半球为负数 + } + + $list['lng_min'] = min([$lngLeft, $curLng, $lngRight]); + $list['lng_max'] = max([$lngLeft, $curLng, $lngRight]); + + $list['lat_top'] = $latTop; + $list['lat_bottom'] = $latBottom; + $list['lng_left'] = $lngLeft; + $list['lng_right'] = $lngRight; + + return $list; + } } \ No newline at end of file diff --git a/app/controller/api/Business.php b/app/controller/api/Business.php new file mode 100644 index 0000000..9dc8e1a --- /dev/null +++ b/app/controller/api/Business.php @@ -0,0 +1,13 @@ + $this->request->param('businessType/d', 0), // 商家类型 + 'couponType' => $this->request->param('couponType/d', 0), // 优惠卷类型 + 'dis' => $this->request->param('dis/d', -1), // 距离,单位为km + 'lng' => $this->request->param('lng/f', 0), // 经度 104.752890 + 'lat' => $this->request->param('lat/f', 0), // 纬度 31.465040 + 'keyword' => $this->request->param('key/s', ''), // 关键词查询 + 'page' => $this->request->param('page/d', 1), + 'size' => $this->request->param('size/d', 10), + ]; + + + try { + $repo = CouponRepository::getInstance(); + $nowDate = date('Y-m-d H:i:s'); + $sumPoint = $params['lng'] + $params['lat']; + + $lngRange = []; + $latRange = []; + $whereMap = []; + $sortOrder = ['dislatlng'=> 'asc', 'start_time'=>'asc']; + + $whereMap[] = ['status', '=', CouponMain::status_on]; + $whereMap[] = ['on_shelf', '=', CouponMain::on_shelf_on]; + $whereMap[] = ['start_time', '> TIME', $nowDate]; + $whereMap[] = ['end_time', '< TIME', $nowDate]; + $whereMap[] = ['using_count', '>', 0]; + if (!empty($params['keyword'])) { + $whereMap[] = ['name', 'like', "%{$params['keyword']}%"]; + } + if ($params['businessType'] > 0) { + $whereMap[] = ['business_type', '=', $params['businessType']]; + } + if ($params['couponType'] > 0) { + $whereMap[] = ['type', '=', $params['couponType']]; + } + + if ($params['dis'] > 0) { + $pointList = getEarthSquareRangePoint($params['lat'],$params['lng'], $params['dis']); + $latRange[] = ['lat', 'BETWEEN', [$pointList['lat_min'], $pointList['lat_max']]]; + if (abs($pointList['cur_lng'] - $pointList['lng_min']) != $pointList['dis_lng'] && $pointList['lng_min'] < 0) { + $lngRange[] = ['lng', 'BETWEEN' , [-180, $pointList['lng_min']]]; + $lngRange[] = ['lng', 'BETWEEN' , [($pointList['cur_lng'] - $pointList['dis_lng']), 180]]; + } else { + $lngRange[] = ['lng', 'BETWEEN' , [$pointList['lng_min'], $pointList['lng_max']]]; + } + } + + $res = $repo->findCouponMainList($whereMap, [], $params['page'], $params['size'], function ($q) use($lngRange, $latRange, $sumPoint) { + return $q->when(!empty($lngRange) && !empty($latRange), function($query) use($lngRange, $latRange){ + $query->where(function ($queryB) use($lngRange) { + $queryB->whereOr($lngRange); + })->where($latRange); + }) + ->field("*, abs(IFNULL(lat,0) + IFNULL(lng,0) - {$sumPoint})as dislatlng"); + }, $sortOrder); + + return $this->json(0, 'success', $res); + } catch (\Exception $e) { + return $this->json(0, 'success', [ + "total" => 0, + "current" => $params['page'], + "size" => $params['size'], + "list" => new Collection() + ]); + } + + } + +} \ No newline at end of file diff --git a/app/controller/api/User.php b/app/controller/api/User.php index 3b06d4d..0bd49cf 100644 --- a/app/controller/api/User.php +++ b/app/controller/api/User.php @@ -117,4 +117,9 @@ class User extends Base } + public function test() + { + + } + } \ No newline at end of file diff --git a/app/repository/CouponRepository.php b/app/repository/CouponRepository.php index bbe516a..69dfe18 100644 --- a/app/repository/CouponRepository.php +++ b/app/repository/CouponRepository.php @@ -5,6 +5,7 @@ namespace app\repository; use app\exception\RepositoryException; use app\model\CouponMain; use app\service\Repository; +use Exception; use think\Model; /** @@ -29,4 +30,21 @@ class CouponRepository extends Repository return CouponMain::where($where); } + /** + * 查询商家发布的优惠卷列表 + * + * @param array $where + * @param array $fields + * @param int $page + * @param int $size + * @param callable|null $call + * @param array $sortOrder + * @return array + * @throws Exception + */ + public function findCouponMainList(array $where, array $fields = [], int $page=1, int $size = 0, callable $call=null, array $sortOrder= []): array + { + return CouponMain::findList($where, $fields, $page, $size, $call, $sortOrder); + } + } \ No newline at end of file From 491703e67a6b3f2153921344a83cbc01769438d7 Mon Sep 17 00:00:00 2001 From: zwesy Date: Mon, 29 Nov 2021 09:50:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=EF=BC=9A=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=B5=8B=E8=AF=95=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- app/controller/api/Consumer.php | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 79e5639..fca1daa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ public/storage/* /Test.php nginx.htaccess dump.rdb -/app/controller/api/Test.php \ No newline at end of file +/app/controller/api/Test.php +/view/error/test.html \ No newline at end of file diff --git a/app/controller/api/Consumer.php b/app/controller/api/Consumer.php index 4729815..b5296ca 100644 --- a/app/controller/api/Consumer.php +++ b/app/controller/api/Consumer.php @@ -4,6 +4,7 @@ namespace app\controller\api; use app\model\CouponMain; use app\repository\CouponRepository; use think\Collection; +use think\response\Json; /** * 消费者端:游客、普通用户 @@ -17,6 +18,10 @@ class Consumer extends Base 'home', ]; + /** + * 获取附近商家发布的优惠卷 + * @return Json + */ public function home() { $params = [