文件
mashangyoujiu/Application/Common/Model/StoreServiceAreaModel.class.php

196 行
6.2 KiB
PHP
可执行文件

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace Common\Model;
use Think\Model;
/**
* 门店服务区域模型
* Class StoreServiceAreaModel
* @package Common\Model
*/
class StoreServiceAreaModel extends BaseModel
{
protected $tableName = 'store_service_area';
protected $fields = array(
'id', // int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID'
'store_id', // int(11) NOT NULL COMMENT '门店ID,关联ls_retail_store表'
'merchant_id', // int(11) NOT NULL COMMENT '商户ID'
'area_name', // varchar(100) NOT NULL DEFAULT '' COMMENT '服务区域名称'
'polygon_data', // text NOT NULL COMMENT '多边形坐标数据,JSON格式存储经纬度数组'
'center_lat', // decimal(10,7) DEFAULT NULL COMMENT '区域中心点纬度'
'center_lng', // decimal(10,7) DEFAULT NULL COMMENT '区域中心点经度'
'area_size', // decimal(15,2) DEFAULT '0.00' COMMENT '服务区域面积(平方公里)'
'delivery_fee', // decimal(8,2) DEFAULT '0.00' COMMENT '该区域配送费用'
'min_order_amount', // decimal(8,2) DEFAULT '0.00' COMMENT '该区域最低起送金额'
'status', // tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1=启用,0=禁用'
'priority', // int(3) NOT NULL DEFAULT '0' COMMENT '优先级,数字越大优先级越高'
'create_time', // int(11) NOT NULL DEFAULT '0' COMMENT '创建时间'
'update_time', // int(11) NOT NULL DEFAULT '0' COMMENT '更新时间'
'operator_id', // int(11) DEFAULT '0' COMMENT '操作员ID'
'remarks', // varchar(500) DEFAULT '' COMMENT '备注说明'
);
/**
* 获取门店的服务区域列表
* @param int $storeId 门店ID
* @param int $status 状态筛选,null为全部
* @return array
*/
public function getStoreServiceAreas($storeId, $status = null)
{
$map = array('store_id' => $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);
}
}