zoukankan      html  css  js  c++  java
  • 电商活动唯一排序时间冲突检测,活动时间区块检测冲突

    其实很多电商活动时间排序的时候需要唯一,比如秒杀活动,必须唯一时间段

    正常来说活动开始之后,应该不能修改活动时间,可以修改内容或者活动商品,如果修改时间冲突问题会很大,活动时间检测就会很麻烦

    这里给一个穷举规则的解决办法,开发框架是laravel

    下面是demo

    数据表

    CREATE TABLE `mao_free_delivery` (
     `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
     `title` varchar(50) NOT NULL COMMENT '活动标题',
     `sum_money` decimal(10,2) unsigned NOT NULL COMMENT '满包邮的金额',
     `shop_id` int(10) unsigned NOT NULL COMMENT '创建者门店ID',
     `user_id` int(10) unsigned NOT NULL COMMENT '创建者用户ID',
     `start_time` timestamp NULL DEFAULT NULL COMMENT '活动开始时间',
     `end_time` timestamp NULL DEFAULT NULL COMMENT '活动结束时间',
     `division_method` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '1是全场,2是部分商品,3是按品类划分',
     `ids` varchar(5000) DEFAULT NULL COMMENT 'ID集合',
     `created_at` timestamp NULL DEFAULT NULL COMMENT '活动创建时间',
     `updated_at` timestamp NULL DEFAULT NULL COMMENT '活动操作更新时间',
     `is_enabled` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '上下架,1是默认,2是下架',
     `is_del` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '是否删除,1是默认,2是删除',
     `sort` int(10) unsigned NOT NULL DEFAULT '255' COMMENT '排序',
     PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='包邮活动表';
    

     

     //包邮检查活动编辑,会和其他的活动时间冲突
        public static function check_time_conflict($shop_id =null,$start_time = null,$end_time = null,$id = null,&$error = null)
        {
              if(empty($start_time)){
                $error = '开始时间不能为空';
                return FALSE;
            }
            if(empty($end_time)){
                $error = '结束时间不能为空';
                return FALSE;
            }
            if(strtotime($start_time) > strtotime($end_time)){
                $error = '开始时间不能大于结束时间';
                return FALSE;
            }
            if(strtotime($start_time) == strtotime($end_time)){
                $error = '开始时间不能等于结束时间';
                return FALSE;
            }
            $condition[]=['is_del', '=', self::IS_DEL];
        $condition[]=['is_enabled', '=', self::IS_ENABLED];
            $condition[]=['shop_id', '=', $shop_id];
            $result = self::getFreeDeliveryInfo($condition);
            if(empty($result)){//没有数据就直接加入
                return true;
            }
            if($id){//编辑时候剔除当前编辑的数据,在进行处理
                foreach ($result as $k1 => $v1) {
                    if(in_array($id,$v1)){
                        unset($result[$k1]);
                    }
                }
            }
    //        pp($result);
             //首先进行时间区块排序,然后进行进行区块比较
            $need = [];
            foreach ($result as $key => &$value) {//转成时间,防止其他php版本出错
                $need[] = $value['start_time'] = strtotime($value['start_time']);
                $need[] = $value['end_time'] = strtotime($value['end_time']);
            }
            //先冒泡排序,在校验进入数组和原数组,防止数据错误
            $bubble_sort_result =  self::bubbleSort($need);
            foreach ($result as $k=> $v) {//数据校验,把原数组的start_time,end_time进行查找如果,如果2个键名的key相等或者相差大于1就是数据出错
              if(!in_array($v['start_time'],$bubble_sort_result)){
                  $error = '数据校验出错,没有检测到开始时间';
                  return FALSE;
              }
              if(!in_array($v['end_time'],$bubble_sort_result)){
                  $error = '数据校验出错,没有检测到结束时间';
                  return FALSE;
              }
              
              $start = array_search($v['start_time'],$bubble_sort_result);
              $end   = array_search($v['end_time'],$bubble_sort_result);
              
              if($start == $end){
                  $error = '数据校验出错,开始时间和结束时间相同';
                  return FALSE;
              }
              
              if($end - $start >1){
                  $error = '数据校验出错,时间排序出错';
                  return FALSE;
              }
            }
    
            //首先进行边界判断,在循环判断
            if(strtotime($start_time) < $bubble_sort_result['0'] && strtotime($end_time) < $bubble_sort_result['0']){//结束时间必须小于对比数组第一个元素,否侧冲突
                      return true;
            }
            if(strtotime($start_time) > $bubble_sort_result[(count($bubble_sort_result)-1)] && strtotime($end_time) > $bubble_sort_result[(count($bubble_sort_result)-1)] ){
                      return true;
            }
            foreach ($bubble_sort_result as $kk => $vv) {
                //其他中间元素必须在01   23  45  67  89中间
                  if($kk % 2 == 1){
                      if(strtotime($start_time) > $bubble_sort_result[$kk] && strtotime($end_time) < $bubble_sort_result[$kk+1]){
                             return true;
                       }
                  }
            }
            $error = '时间排序错误,请不要输入与他活动开始或结束活动相同的时间';
            return FALSE;
        }
        public static function bubbleSort(array $arr = []){
                $len=count($arr);
              //设置一个空数组 用来接收冒出来的泡
              //该层循环控制 需要冒泡的轮数
              for($i=1;$i<$len;$i++)
              { //该层循环用来控制每轮 冒出一个数 需要比较的次数
                for($k=0;$k<$len-$i;$k++)
                {
                   if($arr[$k]>$arr[$k+1])
                    {
                        $tmp=$arr[$k+1];
                        $arr[$k+1]=$arr[$k];
                        $arr[$k]=$tmp;
                    }
                }
              }
              return $arr;
        }
        
        public static function getFreeDeliveryInfo(array $condition = []){
            if(empty($condition)){
                return FALSE;
            }
            $freedeliveryM = new freedeliveryM();
            $res = $freedeliveryM->where($condition)->get();
            if ($res) {
                return $res->toArray();
            }
            return FALSE;
        }
    foreach ($bubble_sort_result as $kk => $vv) {
                //其他中间元素必须在01   23  45  67  89中间
                  if($kk % 2 == 1){
                      if(strtotime($start_time) > $bubble_sort_result[$kk] && strtotime($end_time) < $bubble_sort_result[$kk+1]){
                             return true;
                       }
                  }
            }

     最难理解就是这里,其实就是在01   23     45    67    89中间,K=1的就是检查 1和2中间,适不适合插入新的开始时间和结束时间,合适就返回true

    我是穷举,如果中了一个就可以插入,不能就返回false,还有注意不能在新插入的时间,不能和其他任意一个活动的开始或者结束时间相同,因为要冒泡排序,

    相同就会在检测数据出错,在前端使用插件插入时间的时候,提示用户加一秒就可以

  • 相关阅读:
    bzoj3473 字符串
    洛谷P4070 生成魔咒
    洛谷P3975 弦论
    AT1219 歴史の研究
    课上讲的几个新的技巧
    索引与视图(转载)
    oracle中的分支与循环语句
    Oracle to_date()函数的用法《转载》
    自定义函数的存储过程的区别
    UNION 和 UNION ALL 操作符
  • 原文地址:https://www.cnblogs.com/zx-admin/p/7687147.html
Copyright © 2011-2022 走看看