文件
mashangyoujiu/Application/Common/Business/Store.class.php

746 行
30 KiB
PHP
可执行文件

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

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

<?php
namespace Common\Business;
use Common\Model\CitysModel;
use Common\Model\RetailFranchiseeModel;
use Common\Model\RetailGoodsModel;
use Common\Model\RetailMerchantModel;
use Common\Model\RetailStoreModel;
use Common\Model\RetailStoreXcxConfigModel;
use Common\Model\StoreConfigModel;
use Common\Model\StoreJurisdictionModel;
use LittleGift\Business\LittleGift;
use Retail\Model\GoodsLabelLinkModel;
use Retail\Model\LabelInventoryModel;
//[1.9.20]
/**
* 门店类
* Class Store
*[
* 获取指定门店供货商类型 getSupplierType
* 获取指定门店的指定信息 getAppointStoreInfo
* 所有的门店信息 storeListInfo
* 获取门店配置-赊销配置 getCreditConfig
* 获取门店名称-针对商户大量列表数据读取门店 getStoreName
* 门店名称列表 storeNameList
* 获取门店列表(所有) getStoreList
* 获取门店列表(分页/可搜索) getStoreLimitList
* 门店新增/编辑封装 operateStoreInfo
* ]
* @package Common\Business
*/
class Store
{
/**
* 获取指定门店供货商类型
* @param $store_id
* @return mixed
* [
* supplier_type 1普通供货商 2寄售供货商
* ]
*/
public function getSupplierType($store_id)
{
$StoreModel = new RetailStoreModel();
$supplier_type = $StoreModel->getFindField(['id' => $store_id], "supplier_type");
return $supplier_type;
}
/**
* 获取指定门店的指定信息
* @param $param
* [
* merchant_id
* store_id_gather 门店id集合
* fields 指定字段
* ]
* @return mixed
*/
public function getAppointStoreInfo($param)
{
$where = [
'id' => ['in', $param['store_id_gather']]
];
$fields = $param['fields'] ? $param['fields'] : "*";
try {
$StoreModel = new RetailStoreModel();
$list = $StoreModel->getSelect($where, $fields, 'id asc', '');
return $list ? $list : [];
} catch (\Exception $e) {
return [];
}
}
/**
* 门店列表信息(开启和关闭的门店)
* @param $param
* [
* fields 查询的字段
* merchant_id
* state 0正常 1删除 2包含正常与删除
* ]
* @return mixed
*/
public function storeListInfo($param)
{
$where = [
'merchantid' => $param['merchant_id'],
];
if ($param['state'] != 2) {
$where['state'] = isset($param['state']) ? $param['state'] : 0;
}
$fields = $param['fields'] ? $param['fields'] : "*";
try {
$StoreModel = new RetailStoreModel();
$list = $StoreModel->getSelect($where, $fields, 'id desc', '');
return $list;
} catch (\Exception $e) {
return [];
}
}
/**
* 门店名称列表
* @param $param
* [
* store_id_gather 门店id 集合
* ]
* @return mixed
*/
public function storeNameList($param)
{
try {
$StoreModel = new RetailStoreModel();
$list = $StoreModel->getFindField([
'id' => ['in', $param['store_id_gather']]
], "storetag", true);
return callBack(statusCode()['success'], "查询成功", ['list' => $list]);
} catch (\Exception $e) {
return callBack(statusCode()['success'], "查询成功", ['list' => []]);
}
}
/**
* 获取门店列表(开启和关闭的门店)
* @param $parameter
* [
* merchant_id
* ]
* @return mixed
*/
public function getStoreList($parameter)
{
try {
$where = array(
'merchantid' => $parameter['merchant_id'],
'state' => 0,
);
$storeModel = new RetailStoreModel();
$storeList = $storeModel->getSelect($where, "id,storetag");
return $storeList;
} catch (\Exception $e) {
return [];
}
}
/**
* 获取门店列表接口,仅获取ID和名称(门店开启关闭状态可筛选,可搜索)
* @param $param
* $param['merchant_id'] 商户ID
* $param['industry_id'] 筛选的行业ID
* $param['strict_industry']是否是严格模式筛选行业下的门店 1开启 0关闭
* $param['store_name'] 门店名称(模糊搜索)
* $param['store_status'] 1开启的门店 2关闭的门店 3开启和关闭的门店
* $param['page'] 页码
* $param['limit'] 每页获取数量
* @return Array
*/
public function getStoreLimitList($param)
{
$param['page'] = is_numeric($param['page']) ? $param['page'] : 1;
$param['limit'] = is_numeric($param['limit']) ? $param['limit'] : 10;
$StoreModel = new RetailStoreModel();
$map = array(
'merchantid' => $param['merchant_id'],
'store_status' => $param['store_status'] == 1 ? 0 : ($param['store_status'] == 2 ? 1 : ['in', '0,1']),
'state' => 0,
);
if (!empty($param['store_name'])) {
$map['storetag'] = array('like', '%' . $param['store_name'] . '%');
}
if (!empty($param['industry_id'])) {
if ($param['strict_industry'] == 1) {
$map['industry_id'] = $param['industry_id'];
} else {
$map['industry_id'] = ['in', [0, $param['industry_id']]];
}
}
$list = $StoreModel->getSelect($map, 'id,storetag as store_name,store_status,industry_id', 'store_status asc,id asc', $param['page'] . ',' . $param['limit']);
return callBack(statusCode()['success'], empty($list) ? '暂无数据' : '获取成功', $list);
}
/**
* 获取门店名称-针对商户大量列表数据读取门店
* @param $store_id 门店id
* @param array $store_List 临时处理的门店名称列表
* @return mixed|string
*/
public function getStoreName($store_id = null, &$store_List = array())
{
if (!$store_id) {
return '';
}
try {
if (!$store_List[$store_id]) {
$StoreModel = new RetailStoreModel();
$store_List[$store_id] = $StoreModel->getFindField(array('id' => $store_id), 'storetag');
}
} catch (\Exception $e) {
return '未知门店';
}
return $store_List[$store_id] ? $store_List[$store_id] : '未知门店';
}
/**
* 获取门店配置-赊销配置
* @param $store_id 门店id
* @return mixed|string
*/
public function getCreditConfig($store_id = null, $field = 'is_credit, credit_num, credit_quota')
{
if (!$store_id) {
return ['status' => 0, 'msg' => '门店参数缺失!'];
}
$StoreModel = new StoreConfigModel();
$store = $StoreModel->getFind(['store_id' => $store_id], $field);
if (!$store) {
return ['status' => 0, 'msg' => '门店信息有误!'];
}
return $store;
}
/**
* 门店新增/修改 2021年1月19日09:44:20
* @param $param
* [
* merchant_id
* platform_type 商户平台类型 1默认系统 2微礼平台
* third_code 对应的第三方平台的门店编码
* ]
* @return array
* @author GuYunQinFeng
*/
public function operateStoreInfo($param)
{
$FranchiseeModel = new RetailFranchiseeModel();
$StoreJurisdictionModel = new StoreJurisdictionModel();
$StoreModel = new RetailStoreModel();
$merchant_id = $param['merchant_id'];
$platform_type = $param['platform_type'] ? $param['platform_type'] : 1;
if (
empty($param['latitude']) || empty($param['longitude'])
|| empty($param['address']) || empty($param['dadastatus'])
|| empty($param['store_class']) || empty($param['province_id'])
|| empty($param['city_id']) || empty($param['area_id'])
) {
return ['status' => 0, 'msg' => '请完善基本信息'];
}
// 判断是否存在门店id
$storeItem = [
'storetag' => $param['storetag'],
'shopimg_id' => $param['shopimg_id'],
'merchantid' => $merchant_id,
'longitude' => $param['longitude'],
'latitude' => $param['latitude'],
'address' => $param['address'],
'industry_id' => $param['industry_id'] ? $param['industry_id'] : 0,
'detail_address' => $param['detail_address'],
'dadastatus' => $param['dadastatus'] == 2 ? 2 : 1,
'attribute' => $param['attribute'],
'origin_shop_id' => $param['origin_shop_id'],
'username' => $param['username'],
'password' => $param['password'],
];
$CitysModel = new CitysModel();
$storeItem['province'] = $CitysModel->getFindField(['cityid' => $param['province_id']], 'city_name');
$storeItem['city'] = $CitysModel->getFindField(['cityid' => $param['city_id']], 'city_name');
$storeItem['area'] = $CitysModel->getFindField(['cityid' => $param['area_id']], 'city_name');
//达达商家信息判断
if ($param['dadastatus'] == 2) {
if (empty($param['attribute']) || empty($param['origin_shop_id'])) {
return ['status' => 0, 'msg' => '请完善达达门店类型与门店编码'];
}
if (empty($param['username']) || empty($param['password'])) {
return ['status' => 0, 'msg' => '请完善达达商家账号和密码'];
}
}
// 加盟店信息判断
if ($param['store_class'] == 2) {
if (empty($param['account_number']) || empty($param['name'])) {
return ['status' => 0, 'msg' => '加盟点收款账户不能为空'];
}
if (!in_array($param['clearing_form'], ['1', '2', '3'])) {
return ['status' => 0, 'msg' => '加盟店结算类型有误'];
}
if ($param['clearing_form'] == 1 && empty($param['opening_bank'])) {
return ['status' => 0, 'msg' => '请选择加盟店结算开户行'];
}
if (isset($param['rate'])) {
if (is_numeric($param['rate']) && floatval($param['rate']) >= 0) {
$rate = explode('.', $param['rate']);
// 费率大小判断
if ($rate[0] >= 100) {
return ['status' => 0, 'msg' => '费率不能大于100%'];
}
// 费率小数点位数判断
if (strlen($rate[1]) > 2) {
return ['status' => 0, 'msg' => '费率的小数不能超过两位'];
}
} else {
return ['status' => 0, 'msg' => '费率必须是大于等于0的数字'];
}
} else {
return ['status' => 0, 'msg' => '费率不能为空'];
}
$franchiseItem['rate'] = $param['rate'];
$franchiseItem['account_number'] = $param['account_number'];
$franchiseItem['name'] = $param['name'];
$franchiseItem['type'] = $param['period_radio'];
$franchiseItem['clearing_form'] = $param['clearing_form'];
if ($franchiseItem['clearing_form'] == 1) {
$franchiseItem['opening_bank'] = $param['opening_bank'];
}
}
//新增门店时微礼平台验证参数
if ($platform_type == 2 && empty($param['id'])) {
if (empty($param['third_code'])) {
return ['status' => 0, 'msg' => '请输入Q3 ERP门店编码'];
}
$id = $StoreModel->getFindField([
'state' => 0,
'third_code' => $param['third_code'],
'merchantid' => $merchant_id
], 'id');
if (!empty($id)) {
return ['status' => 0, 'msg' => '该门店编码已存在'];
}
$ThirdClass = new Third();
$thirdResult = $ThirdClass->storeCodeVerify([
'merchant_id' => $merchant_id,
'platform_type' => $platform_type,
'type' => 2,
'third_code' => $param['third_code']
]);
if ($thirdResult['status'] == 0) {
return ['status' => 0, 'msg' => 'Q3 ERP平台编码验证失败' . $thirdResult['message']];
}
$storeItem['third_code'] = $param['third_code'];
} else if ($param['third_code'] && empty($param['id'])) {
$storeItem['third_code'] = $param['third_code'];
}
if (!empty($param['id'])) {
// 编辑操作
$store_id = $param['id'];
$store = $StoreModel->getFind(['id' => $store_id, 'merchantid' => $merchant_id]);
if (empty($store)) {
return ['status' => 0, 'msg' => '您的访问有误'];
}
// if ($store['industry_id'] && empty($param['industry_id'])) {
// return ['status' => 0, 'msg' => '暂不支持取消行业'];
// }
// 行业id处理、存在旧行业且修改行业
if ($param['industry_id'] && $store['industry_id'] && $param['industry_id'] != $store['industry_id']) {
// 是否存在商品标签使用
$LabelInventoryModel = new LabelInventoryModel();
$labelArrMap = [
'status' => 1,
'industry_id' => $store['industry_id'],
];
// 查询门店+行业id下全部标签
$labelIdArr = $LabelInventoryModel->getFindField($labelArrMap, 'id', true);
if ($labelIdArr) {
//查询商品是否存在使用该行业的标签
$GoodsLabelLinkModel = new GoodsLabelLinkModel();
foreach ($labelIdArr as $val) {
$inLinkUse = $GoodsLabelLinkModel->getFind(['label_id' => $val, 'store_id' => $store_id], 'id');
if ($inLinkUse) {
return ['status' => 0, 'msg' => '当前门店存在商品使用了原行业的标签,暂不可修改行业'];
}
}
}
//判断该门店的商品是否有使用的分类属于该行业的
$RetailGoodsModel = new RetailGoodsModel();
$inUseMap = [
'goods.store_id' => $store_id,
'goods.status' => ['in', '0,1'], //商品状态 0,正常,1,下架,2,删除。
'class.status' => 0, //商品分类状态 0,正常,1,删除。
'industry.status' => 1, //行业状态 1正常 2删除
];
$inUseNum = $RetailGoodsModel->getStoreIsUseClassIndustry($inUseMap);
if ($inUseNum > 0) {
return ['status' => 0, 'msg' => '当前门店的商品有使用属于该行业的分类'];
}
}
$res = $StoreModel->updateOrder(['id' => $store_id, 'merchantid' => $merchant_id], $storeItem);
// 修改加盟店配置信息
if ($store['store_class'] == 2) {
$result = $FranchiseeModel->updateOrder(array('store_id' => $store_id), $franchiseItem);
}
if ($res || $result) {
//操作日志记录
$source = 0; //请求来源: 0pc系统 1小助手
$type = 3; //平台:1合伙人端 2代理商端 3商户端 4门店端
$request_data = json_encode($_POST); //请求参数 json数据
$desc = '编辑门店信息'; //操作行为描述
action_log($source, $type, $request_data, $desc);
return ['status' => 1, 'msg' => '编辑成功'];
} else {
return ['status' => 0, 'msg' => '未更新'];
}
} else {
// 新增操作
$storeNum = $StoreModel->getCount(['merchantid' => $merchant_id, 'state' => 0]);
$MerchantModel = new RetailMerchantModel();
$mer_store_num = $MerchantModel->getFindField(['id' => $merchant_id], 'storenum');
if ($mer_store_num <= $storeNum) {
return ['status' => 0, 'msg' => '添加失败:添加门店已超过可创建门店数'];
}
$one = $StoreModel->getCount(['merchantid' => $merchant_id, 'store_type' => 0]);
$storeItem['store_type'] = $one ? 1 : 0;
$storeItem['store_class'] = $param['store_class'];
$storeItem['supplier_type'] = $param['supplier_type'] ? $param['supplier_type'] : 1;
$Role = new Role();
$storeItem['jur_group_id'] = $Role->createSystemGroup([
'type' => 4,
'merchant_id' => $merchant_id,
]);
// 门店信息添加
$res = $StoreModel->addOrder($storeItem);
if (!$res) {
return ['status' => 0, 'msg' => '添加失败'];
}
// 加盟店关联信息
if ($storeItem['store_class'] == 2) {
$franchiseItem['store_id'] = $res;
$franchiseItem['merchant_id'] = $merchant_id;
$franchiseItem['account_type'] = 1; //账号类型:1加盟商 2商户
$franchiseItem['add_time'] = strtotime(date('Y-m-d', time()));
$FranchiseeModel->addOrder($franchiseItem);
}
//添加默认仓库
$content = [
'name' => '默认采购仓',
'number' => 'A_001',
'province' => '北京',
'city' => '北京市',
'area' => '海淀区',
'address' => '北京市海淀区',
'measure_area' => 100,
'person_name' => '小李',
'person_phone' => '18888888888',
'merchant_id' => $merchant_id,
'store_id' => $res,
];
$WarehouseClass = new Warehouse();
$WarehouseClass->storePurchaseWarehouseOperation($content);
$content['name'] = '默认供给仓';
$WarehouseClass->storeSaleWarehouseOperation($content);
$StoreJurisdictionModel->add(['storeid' => $res]);
$StoreConfigModel = new StoreConfigModel();
$StoreConfigModel->addOrder(['store_id' => $res]);
$StoreXcxConfigModel = new RetailStoreXcxConfigModel();
$StoreXcxConfigModel->addOrder(['storeid' => $res]);
//操作日志记录
$source = 0; //请求来源: 0pc系统 1小助手
$type = 3; //平台:1合伙人端 2代理商端 3商户端 4门店端
$request_data = json_encode($param); //请求参数 json数据
$desc = '添加门店'; //操作行为描述
action_log($source, $type, $request_data, $desc);
return ['status' => 1, 'msg' => '添加成功'];
}
}
/**
* 保存门店商城设置
* @param $param
* $param['merchant_id'] 商户ID
* $param['']
* @return mixed
*/
public function storeXcxSet($param)
{
$business_time_verify = $this->handleTime($param['business_time']);
if ($business_time_verify['status'] == 0) {
return callBack(statusCode()['error'], '营业时间' . $business_time_verify['message']);
}
$business_verify = $this->handleTime($param['business']);
if ($business_verify['status'] == 0) {
return callBack(statusCode()['error'], '营业时间' . $business_verify['message']);
}
$item = [
'merchantid' => $param['merchant_id'],//商户id
'status' => $param['status'],//是否开启商城0关闭1开启
'skip' => $param['skip'],//0仅支持商家配送 1不支持商家配送
'self_pick' => $param['self_pick'],//0支持到店自提 1不支持到店自提
'address' => $param['address'],//地址
'latitude' => $param['latitude'],//纬度
'longitude' => $param['longitude'],//经度
'smmoney' => $param['smmoney'],//起送价
'phone' => $param['phone'],//电话
'chek' => $param['chek'],//在配送半径职位是否允许下单 0:允许 1:不允许
'addtime' => time(),//
'math' => $param['math'],//
'tip' => $param['tip'],//
'business_time' => $business_time_verify['data'],
'business' => $business_verify['data'],
'open_freight_collect' => $param['open_freight_collect'],
'business_non_order' => $param['business_non_order'] ? $param['business_non_order'] : 2,//非营业时间下单
'delivery_status' => $param['delivery_status'],//免配送费 0关闭 1开启
'delivery_cost' => $param['delivery_cost'],//免配送费门槛
];
$StoreModel = new RetailStoreModel();
$ret = $StoreModel->updateOrder(['id' => $param['store_id']], $item);
// 处理电子围栏数据
if (isset($param['delivery_fences']) && !empty($param['delivery_fences'])) {
$FenceModel = new \Common\Model\StoreDeliveryFenceModel();
$fenceData = is_string($param['delivery_fences']) ? json_decode($param['delivery_fences'], true) : $param['delivery_fences'];
$FenceModel->saveFenceData($param['store_id'], $param['merchant_id'], $fenceData);
}
// 兼容旧的fence_data参数
elseif (isset($param['fence_data']) && !empty($param['fence_data'])) {
$FenceModel = new \Common\Model\StoreDeliveryFenceModel();
$fenceData = is_string($param['fence_data']) ? json_decode($param['fence_data'], true) : $param['fence_data'];
$FenceModel->saveFenceData($param['store_id'], $param['merchant_id'], $fenceData);
}
$express_status = $param['express_status'] ? $param['express_status'] : 0;
$ConfigModel = new StoreConfigModel();
$ConfigModel->setConfig($param['store_id'], ['delivery_template_status' => $express_status]); //修改快递发货状态
$StoreXcxConfigModel = new RetailStoreXcxConfigModel();
$StoreXcxConfigModel->updateOrder(['storeid' => $param['store_id']], [
'send_delayed_time' => $param['send_delayed_time'] ? $param['send_delayed_time'] : 0,
'pickup_delayed_time' => $param['pickup_delayed_time'] ? $param['pickup_delayed_time'] : 0,
'auto_set_time' => $param['auto_set_time'] ? $param['auto_set_time'] : 0,
]);//商城下单订单配送、自提延时的时间(单位:分钟)
if ($ret !== false) {
//操作日志记录
action_log($param['source'], $param['type'], json_encode($_POST), '门店设置-门店信息设置');
return callBack(statusCode()['success'], '保存成功');
} else {
return callBack(statusCode()['error'], '保存失败');
}
}
/**
* 门店设置的自提/配送时间段转换为字符串
* @param array $time_arr
* @return string
*/
private function handleTime($time_arr = [])
{
if (empty($time_arr)) {
return callBack(statusCode()['error'], '至少设置一个');
}
// 检查每个时间段的有效性
foreach ($time_arr as $index => $time_period) {
if (!empty($time_period) && !empty($time_period[0]) && !empty($time_period[1])) {
// 验证时间格式
if (!$this->isValidTimeFormat($time_period[0]) || !$this->isValidTimeFormat($time_period[1])) {
return callBack(statusCode()['error'], '时间格式错误');
}
}
}
// 检查时间段之间的冲突
for ($i = 0; $i < count($time_arr); $i++) {
if (empty($time_arr[$i]) || empty($time_arr[$i][0]) || empty($time_arr[$i][1])) {
continue;
}
for ($j = $i + 1; $j < count($time_arr); $j++) {
if (empty($time_arr[$j]) || empty($time_arr[$j][0]) || empty($time_arr[$j][1])) {
continue;
}
if ($this->isTimeConflict($time_arr[$i], $time_arr[$j])) {
return callBack(statusCode()['error'], '时间段存在冲突');
}
}
}
$time1 = [];
foreach ($time_arr as $key => $val) {
if (!empty($val) && !empty($val[0]) && !empty($val[1])) {
$time1[] = $val[0] . '-' . $val[1];
}
}
return callBack(statusCode()['success'], '成功', implode(',', $time1));
}
/**
* 验证时间格式是否正确
* @param string $time 时间字符串,格式为 HH:MM
* @return bool
*/
private function isValidTimeFormat($time)
{
return preg_match('/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/', $time);
}
/**
* 检查两个时间段是否冲突(支持跨天时间段)
* @param array $time1 时间段1 [开始时间, 结束时间]
* @param array $time2 时间段2 [开始时间, 结束时间]
* @return bool true表示冲突,false表示不冲突
*/
private function isTimeConflict($time1, $time2)
{
$start1 = $time1[0];
$end1 = $time1[1];
$start2 = $time2[0];
$end2 = $time2[1];
// 判断是否为跨天时间段
$isCrossDay1 = $this->isCrossDay($start1, $end1);
$isCrossDay2 = $this->isCrossDay($start2, $end2);
if (!$isCrossDay1 && !$isCrossDay2) {
// 两个都是同一天的时间段
return $this->isNormalTimeConflict($start1, $end1, $start2, $end2);
} else if ($isCrossDay1 && !$isCrossDay2) {
// time1跨天,time2不跨天
return $this->isCrossDayConflictWithNormal($start1, $end1, $start2, $end2);
} else if (!$isCrossDay1 && $isCrossDay2) {
// time1不跨天,time2跨天
return $this->isCrossDayConflictWithNormal($start2, $end2, $start1, $end1);
} else {
// 两个都是跨天时间段
return $this->isCrossDayConflictWithCrossDay($start1, $end1, $start2, $end2);
}
}
/**
* 判断时间段是否跨天
* @param string $start 开始时间
* @param string $end 结束时间
* @return bool
*/
private function isCrossDay($start, $end)
{
return strtotime($start) > strtotime($end);
}
/**
* 检查两个同一天的时间段是否冲突
* @param string $start1 时间段1开始时间
* @param string $end1 时间段1结束时间
* @param string $start2 时间段2开始时间
* @param string $end2 时间段2结束时间
* @return bool
*/
private function isNormalTimeConflict($start1, $end1, $start2, $end2)
{
$startTime1 = strtotime($start1);
$endTime1 = strtotime($end1);
$startTime2 = strtotime($start2);
$endTime2 = strtotime($end2);
return !($endTime1 <= $startTime2 || $endTime2 <= $startTime1);
}
/**
* 检查跨天时间段与普通时间段是否冲突
* @param string $crossStart 跨天时间段开始时间
* @param string $crossEnd 跨天时间段结束时间
* @param string $normalStart 普通时间段开始时间
* @param string $normalEnd 普通时间段结束时间
* @return bool
*/
private function isCrossDayConflictWithNormal($crossStart, $crossEnd, $normalStart, $normalEnd)
{
// 将时间转换为分钟数便于比较
$crossStartMinutes = $this->timeToMinutes($crossStart);
$crossEndMinutes = $this->timeToMinutes($crossEnd);
$normalStartMinutes = $this->timeToMinutes($normalStart);
$normalEndMinutes = $this->timeToMinutes($normalEnd);
// 跨天时间段覆盖两个区间:
// 1. 当天的 crossStart 到 23:59 (crossStartMinutes 到 1439)
// 2. 次日的 00:00 到 crossEnd (0 到 crossEndMinutes)
// 检查普通时间段是否与当天后半部分冲突
$conflict1 = ($normalStartMinutes <= 1439) && ($normalEndMinutes > $crossStartMinutes);
// 检查普通时间段是否与次日前半部分冲突
$conflict2 = ($normalStartMinutes < $crossEndMinutes) && ($normalEndMinutes >= 0);
return $conflict1 || $conflict2;
}
/**
* 检查两个跨天时间段是否冲突
* @param string $start1 时间段1开始时间
* @param string $end1 时间段1结束时间
* @param string $start2 时间段2开始时间
* @param string $end2 时间段2结束时间
* @return bool
*/
private function isCrossDayConflictWithCrossDay($start1, $end1, $start2, $end2)
{
// 将时间转换为分钟数
$start1Minutes = $this->timeToMinutes($start1);
$end1Minutes = $this->timeToMinutes($end1);
$start2Minutes = $this->timeToMinutes($start2);
$end2Minutes = $this->timeToMinutes($end2);
// 两个跨天时间段:
// 时间段1: start1 ~ 23:59 + 00:00 ~ end1
// 时间段2: start2 ~ 23:59 + 00:00 ~ end2
// 检查当天后半部分是否冲突 (start1~23:59 与 start2~23:59)
$conflict1 = !($start1Minutes >= 1439 || $start2Minutes >= 1439) &&
!(($start1Minutes >= $start2Minutes) || ($start2Minutes >= $start1Minutes));
// 检查次日前半部分是否冲突 (00:00~end1 与 00:00~end2)
$conflict2 = !($end1Minutes <= 0 || $end2Minutes <= 0) &&
!(($end1Minutes <= $end2Minutes) || ($end2Minutes <= $end1Minutes));
// 如果两个跨天时间段的开始时间或结束时间有重叠,就认为冲突
return $conflict1 || $conflict2;
}
/**
* 将时间字符串转换为分钟数
* @param string $time 时间字符串 HH:MM
* @return int 从00:00开始的分钟数
*/
private function timeToMinutes($time)
{
list($hour, $minute) = explode(':', $time);
return intval($hour) * 60 + intval($minute);
}
}