$storeId); if ($status !== null) { $map['status'] = $status; } return $this->where($map) ->order('priority DESC, id ASC') ->select(); } /** * 保存服务区域数据 * @param array $data 区域数据 * @return bool|int */ public function saveServiceArea($data) { $data['update_time'] = time(); if (isset($data['id']) && $data['id'] > 0) { // 更新 $id = $data['id']; unset($data['id']); return $this->where(array('id' => $id))->save($data); } else { // 新增 $data['create_time'] = time(); return $this->add($data); } } /** * 删除服务区域 * @param int $id 区域ID * @param int $storeId 门店ID(安全验证) * @return bool */ public function deleteServiceArea($id, $storeId) { return $this->where(array('id' => $id, 'store_id' => $storeId))->delete(); } /** * 更新区域状态 * @param int $id 区域ID * @param int $storeId 门店ID * @param int $status 状态 * @return bool */ public function updateStatus($id, $storeId, $status) { $data = array( 'status' => $status, 'update_time' => time() ); return $this->where(array('id' => $id, 'store_id' => $storeId))->save($data); } /** * 检查坐标点是否在服务区域内 * @param float $lat 纬度 * @param float $lng 经度 * @param int $storeId 门店ID * @return array|false 返回匹配的区域信息,无匹配返回false */ public function checkPointInServiceArea($lat, $lng, $storeId) { $areas = $this->getStoreServiceAreas($storeId, 1); // 只获取启用的区域 foreach ($areas as $area) { if ($this->isPointInPolygon($lat, $lng, $area['polygon_data'])) { return $area; } } return false; } /** * 判断点是否在多边形内(射线法) * @param float $lat 纬度 * @param float $lng 经度 * @param string $polygonData JSON格式的多边形坐标数据 * @return bool */ private function isPointInPolygon($lat, $lng, $polygonData) { $polygon = json_decode($polygonData, true); if (!$polygon || count($polygon) < 3) { return false; } $x = $lng; $y = $lat; $inside = false; $j = count($polygon) - 1; for ($i = 0; $i < count($polygon); $i++) { $xi = $polygon[$i]['lng']; $yi = $polygon[$i]['lat']; $xj = $polygon[$j]['lng']; $yj = $polygon[$j]['lat']; if ((($yi > $y) != ($yj > $y)) && ($x < ($xj - $xi) * ($y - $yi) / ($yj - $yi) + $xi)) { $inside = !$inside; } $j = $i; } return $inside; } /** * 获取区域详情 * @param int $id 区域ID * @param int $storeId 门店ID * @return array|null */ public function getServiceAreaDetail($id, $storeId) { return $this->where(array('id' => $id, 'store_id' => $storeId))->find(); } /** * 计算多边形面积(简单估算,单位:平方公里) * @param string $polygonData JSON格式的多边形坐标数据 * @return float */ public function calculatePolygonArea($polygonData) { $polygon = json_decode($polygonData, true); if (!$polygon || count($polygon) < 3) { return 0; } // 使用鞋带公式计算面积(简化版本) $area = 0; $j = count($polygon) - 1; for ($i = 0; $i < count($polygon); $i++) { $area += ($polygon[$j]['lng'] + $polygon[$i]['lng']) * ($polygon[$j]['lat'] - $polygon[$i]['lat']); $j = $i; } $area = abs($area) / 2; // 转换为平方公里(粗略估算) // 1度经纬度约等于111公里 $areaKm2 = $area * 111 * 111; return round($areaKm2, 2); } }