文件
mashangyoujiu/Application/Retail/Controller/FenceController.class.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;
}
}