500 行
15 KiB
PHP
500 行
15 KiB
PHP
<?php
|
|
|
|
namespace Retail\Controller;
|
|
|
|
use Common\Model\RetailStoreModel;
|
|
use Think\Controller;
|
|
|
|
//[1.8.50]
|
|
|
|
/**
|
|
* 电子围栏管理
|
|
* Class FenceController
|
|
* @package Retail\Controller
|
|
*/
|
|
class FenceController extends BaseController
|
|
{
|
|
/**
|
|
* 初始化
|
|
*/
|
|
public function _initialize()
|
|
{
|
|
parent::_initialize();
|
|
if (empty($this->store_id)) {
|
|
if (IS_POST) {
|
|
$res = array(
|
|
'status' => 0,
|
|
'msg' => '您无权访问该接口',
|
|
);
|
|
$this->ajaxReturn($res);
|
|
} else {
|
|
session(null);
|
|
echo '<script>top.window.location="' . $_SERVER ["SCRIPT_NAME"] . '/Retail/Login/index"</script>';
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 围栏管理页面
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->display();
|
|
}
|
|
|
|
/**
|
|
* 获取围栏列表
|
|
*/
|
|
public function getFenceList()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$store_id = I('post.store_id', $this->store_id);
|
|
$page = I('post.page', 1);
|
|
$size = I('post.size', 10);
|
|
|
|
// 验证参数
|
|
if (!$store_id) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '门店ID不能为空']);
|
|
}
|
|
|
|
$where = [
|
|
'store_id' => $store_id,
|
|
'is_deleted' => 0
|
|
];
|
|
|
|
// 计算总数
|
|
$total = M('ls_store_delivery_fence')->where($where)->count();
|
|
|
|
// 获取列表数据
|
|
$list = M('ls_store_delivery_fence')
|
|
->where($where)
|
|
->order('create_time DESC')
|
|
->page($page, $size)
|
|
->select();
|
|
|
|
$this->ajaxReturn([
|
|
'code' => 200,
|
|
'msg' => '获取成功',
|
|
'data' => [
|
|
'list' => $list ?: [],
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'size' => $size
|
|
]
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 新增围栏
|
|
*/
|
|
public function addFence()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$fence_name = I('post.fence_name');
|
|
$fence_type = I('post.fence_type');
|
|
$fence_data = I('post.fence_data');
|
|
$is_active = I('post.is_active', 1);
|
|
$store_id = I('post.store_id', $this->store_id);
|
|
$merchant_id = I('post.merchant_id', $this->merchant_id);
|
|
|
|
// 验证必填参数
|
|
if (!$fence_name) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏名称不能为空']);
|
|
}
|
|
if (!in_array($fence_type, [1, 2])) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏类型错误']);
|
|
}
|
|
if (!$fence_data) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏数据不能为空']);
|
|
}
|
|
|
|
// 验证围栏数据格式
|
|
$fence_data_array = json_decode($fence_data, true);
|
|
if (!$fence_data_array) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏数据格式错误']);
|
|
}
|
|
|
|
// 验证围栏数据内容
|
|
if ($fence_type == 1) { // 多边形
|
|
if (!isset($fence_data_array['type']) || $fence_data_array['type'] !== 'polygon' ||
|
|
!isset($fence_data_array['coordinates']) || !is_array($fence_data_array['coordinates'])) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '多边形围栏数据格式错误']);
|
|
}
|
|
} else if ($fence_type == 2) { // 圆形
|
|
if (!isset($fence_data_array['type']) || $fence_data_array['type'] !== 'circle' ||
|
|
!isset($fence_data_array['center']) || !isset($fence_data_array['radius'])) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '圆形围栏数据格式错误']);
|
|
}
|
|
}
|
|
|
|
// 检查围栏名称是否重复
|
|
$exists = M('ls_store_delivery_fence')->where([
|
|
'store_id' => $store_id,
|
|
'fence_name' => $fence_name,
|
|
'is_deleted' => 0
|
|
])->find();
|
|
|
|
if ($exists) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏名称已存在']);
|
|
}
|
|
|
|
// 插入数据
|
|
$data = [
|
|
'store_id' => $store_id,
|
|
'merchant_id' => $merchant_id,
|
|
'fence_name' => $fence_name,
|
|
'fence_type' => $fence_type,
|
|
'fence_data' => $fence_data,
|
|
'is_active' => $is_active,
|
|
'create_time' => time(),
|
|
'update_time' => time(),
|
|
'is_deleted' => 0
|
|
];
|
|
|
|
$result = M('ls_store_delivery_fence')->add($data);
|
|
|
|
if ($result) {
|
|
$this->ajaxReturn(['code' => 200, 'msg' => '添加成功', 'data' => ['id' => $result]]);
|
|
} else {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '添加失败']);
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新围栏
|
|
*/
|
|
public function updateFence()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$id = I('post.id');
|
|
$fence_name = I('post.fence_name');
|
|
$fence_type = I('post.fence_type');
|
|
$fence_data = I('post.fence_data');
|
|
$is_active = I('post.is_active', 1);
|
|
$store_id = I('post.store_id', $this->store_id);
|
|
|
|
// 验证必填参数
|
|
if (!$id) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏ID不能为空']);
|
|
}
|
|
if (!$fence_name) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏名称不能为空']);
|
|
}
|
|
if (!in_array($fence_type, [1, 2])) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏类型错误']);
|
|
}
|
|
if (!$fence_data) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏数据不能为空']);
|
|
}
|
|
|
|
// 验证围栏是否存在
|
|
$fence = M('ls_store_delivery_fence')->where([
|
|
'id' => $id,
|
|
'store_id' => $store_id,
|
|
'is_deleted' => 0
|
|
])->find();
|
|
|
|
if (!$fence) {
|
|
$this->ajaxReturn(['code' => 404, 'msg' => '围栏不存在']);
|
|
}
|
|
|
|
// 验证围栏数据格式
|
|
$fence_data_array = json_decode($fence_data, true);
|
|
if (!$fence_data_array) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏数据格式错误']);
|
|
}
|
|
|
|
// 检查围栏名称是否重复(排除当前记录)
|
|
$exists = M('ls_store_delivery_fence')->where([
|
|
'store_id' => $store_id,
|
|
'fence_name' => $fence_name,
|
|
'is_deleted' => 0,
|
|
'id' => ['neq', $id]
|
|
])->find();
|
|
|
|
if ($exists) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏名称已存在']);
|
|
}
|
|
|
|
// 更新数据
|
|
$data = [
|
|
'fence_name' => $fence_name,
|
|
'fence_type' => $fence_type,
|
|
'fence_data' => $fence_data,
|
|
'is_active' => $is_active,
|
|
'update_time' => time()
|
|
];
|
|
|
|
$result = M('ls_store_delivery_fence')->where(['id' => $id])->save($data);
|
|
|
|
if ($result !== false) {
|
|
$this->ajaxReturn(['code' => 200, 'msg' => '更新成功']);
|
|
} else {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '更新失败']);
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 更新围栏状态
|
|
*/
|
|
public function updateFenceStatus()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$id = I('post.id');
|
|
$is_active = I('post.is_active');
|
|
$store_id = $this->store_id;
|
|
|
|
// 验证参数
|
|
if (!$id) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏ID不能为空']);
|
|
}
|
|
if (!in_array($is_active, [0, 1])) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '状态参数错误']);
|
|
}
|
|
|
|
// 验证围栏是否存在
|
|
$fence = M('ls_store_delivery_fence')->where([
|
|
'id' => $id,
|
|
'store_id' => $store_id,
|
|
'is_deleted' => 0
|
|
])->find();
|
|
|
|
if (!$fence) {
|
|
$this->ajaxReturn(['code' => 404, 'msg' => '围栏不存在']);
|
|
}
|
|
|
|
// 更新状态
|
|
$result = M('ls_store_delivery_fence')->where(['id' => $id])->save([
|
|
'is_active' => $is_active,
|
|
'update_time' => time()
|
|
]);
|
|
|
|
if ($result !== false) {
|
|
$this->ajaxReturn(['code' => 200, 'msg' => '状态更新成功']);
|
|
} else {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '状态更新失败']);
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除围栏
|
|
*/
|
|
public function deleteFence()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$id = I('post.id');
|
|
$store_id = $this->store_id;
|
|
|
|
// 验证参数
|
|
if (!$id) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏ID不能为空']);
|
|
}
|
|
|
|
// 验证围栏是否存在
|
|
$fence = M('ls_store_delivery_fence')->where([
|
|
'id' => $id,
|
|
'store_id' => $store_id,
|
|
'is_deleted' => 0
|
|
])->find();
|
|
|
|
if (!$fence) {
|
|
$this->ajaxReturn(['code' => 404, 'msg' => '围栏不存在']);
|
|
}
|
|
|
|
// 软删除
|
|
$result = M('ls_store_delivery_fence')->where(['id' => $id])->save([
|
|
'is_deleted' => 1,
|
|
'update_time' => time()
|
|
]);
|
|
|
|
if ($result !== false) {
|
|
$this->ajaxReturn(['code' => 200, 'msg' => '删除成功']);
|
|
} else {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '删除失败']);
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取围栏详情
|
|
*/
|
|
public function getFenceDetail()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$id = I('post.id');
|
|
$store_id = $this->store_id;
|
|
|
|
// 验证参数
|
|
if (!$id) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '围栏ID不能为空']);
|
|
}
|
|
|
|
// 获取围栏详情
|
|
$fence = M('ls_store_delivery_fence')->where([
|
|
'id' => $id,
|
|
'store_id' => $store_id,
|
|
'is_deleted' => 0
|
|
])->find();
|
|
|
|
if (!$fence) {
|
|
$this->ajaxReturn(['code' => 404, 'msg' => '围栏不存在']);
|
|
}
|
|
|
|
$this->ajaxReturn(['code' => 200, 'msg' => '获取成功', 'data' => $fence]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 检查坐标是否在围栏内
|
|
*/
|
|
public function checkPointInFence()
|
|
{
|
|
if (!IS_POST) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '请求方式错误']);
|
|
}
|
|
|
|
try {
|
|
$lng = I('post.lng');
|
|
$lat = I('post.lat');
|
|
$store_id = I('post.store_id', $this->store_id);
|
|
|
|
// 验证参数
|
|
if (!$lng || !$lat) {
|
|
$this->ajaxReturn(['code' => 400, 'msg' => '经纬度不能为空']);
|
|
}
|
|
|
|
// 获取该门店所有启用的围栏
|
|
$fences = M('ls_store_delivery_fence')->where([
|
|
'store_id' => $store_id,
|
|
'is_active' => 1,
|
|
'is_deleted' => 0
|
|
])->select();
|
|
|
|
$inFence = false;
|
|
$fenceInfo = null;
|
|
|
|
foreach ($fences as $fence) {
|
|
$fence_data = json_decode($fence['fence_data'], true);
|
|
|
|
if ($fence['fence_type'] == 1) { // 多边形
|
|
if ($this->pointInPolygon($lng, $lat, $fence_data['coordinates'][0])) {
|
|
$inFence = true;
|
|
$fenceInfo = $fence;
|
|
break;
|
|
}
|
|
} else if ($fence['fence_type'] == 2) { // 圆形
|
|
if ($this->pointInCircle($lng, $lat, $fence_data['center'], $fence_data['radius'])) {
|
|
$inFence = true;
|
|
$fenceInfo = $fence;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->ajaxReturn([
|
|
'code' => 200,
|
|
'msg' => '检查完成',
|
|
'data' => [
|
|
'in_fence' => $inFence,
|
|
'fence_info' => $fenceInfo
|
|
]
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->ajaxReturn(['code' => 500, 'msg' => '系统错误:' . $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 判断点是否在多边形内(射线法)
|
|
*/
|
|
private function pointInPolygon($lng, $lat, $polygon)
|
|
{
|
|
$count = count($polygon);
|
|
$inside = false;
|
|
|
|
for ($i = 0, $j = $count - 1; $i < $count; $j = $i++) {
|
|
$xi = $polygon[$i][0];
|
|
$yi = $polygon[$i][1];
|
|
$xj = $polygon[$j][0];
|
|
$yj = $polygon[$j][1];
|
|
|
|
if ((($yi > $lat) != ($yj > $lat)) && ($lng < ($xj - $xi) * ($lat - $yi) / ($yj - $yi) + $xi)) {
|
|
$inside = !$inside;
|
|
}
|
|
}
|
|
|
|
return $inside;
|
|
}
|
|
|
|
/**
|
|
* 判断点是否在圆形内
|
|
*/
|
|
private function pointInCircle($lng, $lat, $center, $radius)
|
|
{
|
|
$distance = $this->calculateDistance($lat, $lng, $center[1], $center[0]);
|
|
return $distance <= $radius;
|
|
}
|
|
|
|
/**
|
|
* 计算两点间距离(米)
|
|
*/
|
|
private function calculateDistance($lat1, $lng1, $lat2, $lng2)
|
|
{
|
|
$R = 6371000; // 地球半径(米)
|
|
$dLat = deg2rad($lat2 - $lat1);
|
|
$dLng = deg2rad($lng2 - $lng1);
|
|
$a = sin($dLat/2) * sin($dLat/2) +
|
|
cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
|
|
sin($dLng/2) * sin($dLng/2);
|
|
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
|
|
return $R * $c;
|
|
}
|
|
} |