'', 'mall_id' => '商城id', 'mch_id' => '商家id', 'price' => '售价', 'original_price' => '原价(划线价仅展示)', 'cost_price' => '成本价', 'reserve_max_buy' => '每天最大预约数量', 'reserve_time' => '预约日期标题', 'reserve_sku_id' => '预约商品SKU', 'stock' => '库存', 'sales' => '销量', 'reserve_range_time' => '时分秒时间范围', 'time_span' => '时间间隔(分钟)', 'created_at' => '创建时间', 'updated_at' => '修改时间', ]; } public function getTimeSpec() { return $this->hasMany(GoodsReserveTimeSpec::class, ['reserve_time_id' => 'id']); } // 设置sku的可预约时间 public static function setSkuTime($reserveGoodsSku) { try { $skuId = $reserveGoodsSku['id']; if($reserveGoodsSku['reserve_time_slot_price']){ $reserveTimeSlotPrice = json_decode($reserveGoodsSku['reserve_time_slot_price'], true); }else{ $reserveTimeSlotPrice = []; } //$reserveTimeSlotPrice = json_decode($reserveGoodsSku['reserve_time_slot_price'], true); //$reserveTimeSlotPrice = $reserveGoodsSku['reserve_time_slot_price'] ?? []; // \Yii::error(json_encode([$reserveGoodsSku, $reserveTimeSlotPrice], JSON_UNESCAPED_UNICODE)); $totalStock = 0; // dd($reserveTimeSlotPrice); // 清除规格下的所有时间设置 self::deleteAll(['reserve_sku_id' => $skuId]); GoodsReserveTimeSpec::deleteAll(['reserve_sku_id'=>$skuId]); if($reserveGoodsSku['reserve_time_range_type'] == 1){ //按天预约 $reserve_date = $reserveGoodsSku['reserve_date'] ? json_decode($reserveGoodsSku['reserve_date'],true) : []; foreach($reserve_date as $date){ $model = new self(); $model->loadDefaultValues(); $attributes = [ 'mall_id' => $reserveGoodsSku['mall_id'] ?? 0, 'mch_id' => $reserveGoodsSku['mch_id'] ?? 0, 'price' => $reserveGoodsSku['reserve_price_type'] == 2 ? ($reserveTimeSlotPrice[$date]['price'] ?? 0) : ($reserveGoodsSku['price'] ?? 0), 'original_price' => $reserveGoodsSku['reserve_price_type'] == 2 ? ($reserveTimeSlotPrice[$date]['original_price'] ?? 0) : ($reserveGoodsSku['original_price'] ?? 0), 'cost_price' => $reserveGoodsSku['reserve_price_type'] == 2 ? ($reserveTimeSlotPrice[$date]['cost_price'] ?? 0) : ($reserveGoodsSku['cost_price'] ?? 0), 'reserve_max_buy' => $reserveGoodsSku['reserve_price_type'] == 2 ? ($reserveTimeSlotPrice[$date]['reserve_max_buy'] ?? 0) : ($reserveGoodsSku['reserve_max_buy'] ?? 0), 'reserve_time' => $date, 'reserve_sku_id' => $reserveGoodsSku['id'] ?? 0, 'stock' => $reserveGoodsSku['reserve_price_type'] == 2 ? ($reserveTimeSlotPrice[$date]['reserve_max_buy'] ?? 0) : ($reserveGoodsSku['reserve_max_buy'] ?? 0), 'reserve_range_time' => $reserveGoodsSku['reserve_range_time'] ?? '', 'time_span' => $reserveGoodsSku['time_span'] ?? 0, 'reserve_date' => $date, ]; Yii::error("{$reserveGoodsSku['reserve_time_range_type']} -> " . var_export($attributes, true)); if (!$model->load($attributes, '') || !$model->save()) { throw new Exception($model->getErrorMessage()); } $totalStock += $reserveGoodsSku['reserve_max_buy']; } }else{ // 按时间段 array_map(function ($val) use (&$totalStock, &$reserveGoodsSku) { $model = new self(); $model->loadDefaultValues(); $attributes = [ 'mall_id' => $reserveGoodsSku['mall_id'] ?? 0, 'mch_id' => $reserveGoodsSku['mch_id'] ?? 0, 'price' => $val['price'] ?? 0, 'original_price' => $val['original_price'] ?? 0, 'cost_price' => $val['cost_price'] ?? 0, 'reserve_max_buy' => $val['reserve_max_buy'] ?? 0, 'reserve_time' => $val['reserve_time'] ?? 0, 'reserve_sku_id' => $reserveGoodsSku['id'] ?? 0, 'stock' => $val['reserve_max_buy'] ?? 0, 'reserve_range_time' => $val['reserve_range_time'] ?? '', 'time_span' => $val['time_span'] ?? 0, 'reserve_date' => $val['reserve_time'] ?? date('Y-m-d'), ]; Yii::error("{$reserveGoodsSku['reserve_time_range_type']} -> " . var_export($attributes, true)); if (!$model->load($attributes, '') || !$model->save()) { throw new Exception($model->getErrorMessage()); } // 有时间段设置 if (!empty($val['time_spec'])) { $timeMdl = ArrayHelper::toArray($model); $res = GoodsReserveTimeSpec::setTimeSpec($timeMdl, $val['time_spec'], $totalStock); if($res === false) throw new Exception('处理预约商品预约时间规格异常,msg:'.GoodsReserveTimeSpec::getStaticError()); } else { $totalStock += $val['reserve_max_buy']; } }, $reserveTimeSlotPrice); } if ($totalStock > 0) { $goods = Goods::findOne($reserveGoodsSku['goods_id']); $goods->stock = +$totalStock; if (!$goods->save()) throw new Exception($goods->getErrorMessage()); } } catch (Exception $e) { if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * 获取商品规格预约时间 * @param $mall_id * @param array $sku * @param int $limit * @return array|\yii\db\ActiveRecord[] */ public static function getSkuTime($mall_id,$sku,$limit = 20) { $reserve_date = $sku['reserve_date']; $reserve_date = $reserve_date ? json_decode($reserve_date,true) : []; $reserve = GoodsReserve::findOne(['goods_id' => $sku['goods_id']]); $reserve_days_range = $reserve['reserve_days_range'] ?: 30; $reserve_advance_hourse = $reserve['reserve_advance_hourse'] ?:0; $reserve_advance_hourse_time = $reserve_advance_hourse > 0 ? strtotime("+$reserve_advance_hourse hour") : 0; $max_reserve_time = strtotime(date('Y-m-d',strtotime("+$reserve_days_range days"))); $reserve_date_arr = []; foreach($reserve_date as $date){ $date_timestamp = strtotime($date); if($date_timestamp >= strtotime(date('Y-m-d')) && $date_timestamp <= $max_reserve_time){ $reserve_date_arr[] = $date_timestamp; } } $max_reserve_date = $reserve_date_arr ? date('Y-m-d',max($reserve_date_arr)) : date('Y-m-d'); $reserve_sku_id = $sku['id']; //reserve_time_range_type = 1 按天预约 timeSpec 为空 $list = self::find()->where(['mall_id' => $mall_id,'reserve_sku_id' => $reserve_sku_id]) ->with(['timeSpec' => function($query){ $query->select('id as time_spec_id, reserve_time_id,spec_time,price');}]) ->andWhere(['>=','reserve_date',date('Y-m-d')]) ->andWhere(['<=','reserve_date',$max_reserve_date]) ->orderBy('reserve_date asc') ->limit($limit) ->select('id,price,original_price,cost_price,reserve_time,reserve_sku_id,reserve_max_buy,reserve_date') ->asArray()->all(); //提前预约reserve_advance_hourse // dd($list); $next_arr = []; // $next_day = null; foreach ($list as $key => $val){ $val['week_day'] = self::getWeekDay($val['reserve_time']); if($val['timeSpec']){ foreach($val['timeSpec'] as $k => $v){ $spec_time = explode('-',$v['spec_time']); $start_date_time = $val['reserve_time'].' '.$spec_time[0].':00'; $end_date_time = $val['reserve_time'].' '.$spec_time[1].':00'; $start_time = strtotime($start_date_time); if (strpos($end_date_time, '次日') !== false) { $end_date_time_arr = explode(" ", $end_date_time); $end_time = strtotime("$end_date_time_arr[0] 23:59:59"); $list[$key]['timeSpec'][$k]['spec_time'] = "{$spec_time[0]}-23:59:59"; $next = $key+1; // if (empty($list[$next])) { // $next_day = $val; // } $next_arr[$next] = $v; } else { $end_time = strtotime($end_date_time); } if(time() >= $end_time || $reserve_advance_hourse_time > $end_time){ unset($val['timeSpec'][$k]); continue; } if(time() > $start_time && time() < $end_time){ $v['spec_time'] = date("H:00").'-'.$spec_time[1]; if($reserve_advance_hourse_time > $start_time){ $v['spec_time'] = date("H:00",$reserve_advance_hourse_time).'-'.$spec_time[1]; } if (strpos($v['spec_time'], "次日") !== false) { $v['spec_time'] = "$spec_time[0]-23:59"; } $val['timeSpec'][$k] = $v; } else { if (strpos($v['spec_time'], "次日") !== false) { $v['spec_time'] = "$spec_time[0]-23:59"; } $val['timeSpec'][$k] = $v; } } $val['timeSpec'] = array_values($val['timeSpec']); } $list[$key] = $val; } if (!empty($next_arr)) { foreach ($list as $key => &$item) { if (!empty($next_arr[$key])) { $tmp_v = $next_arr[$key]; $time_arr = explode("次日", $tmp_v['spec_time']); $tmp_v['spec_time'] = "00:00-{$time_arr[1]}"; $item['timeSpec'][] = $tmp_v; } } } //dd($list); return $list; } /** * 获取商品最近可预约时间 * @param $mall_id * @param $goods_id * @param $reserve_sku_ids * @return array */ public static function getSkuLatelyTime($mall_id,$goods_id,$reserve_sku_ids) { $where = ['mall_id' => $mall_id,'reserve_sku_id' => $reserve_sku_ids]; $min_date = self::find()->where($where) ->andWhere(['>=','reserve_date',date('Y-m-d')])->groupBy('reserve_sku_id') ->select("min(reserve_date) as reserve_date")->asArray()->all(); $min_date = array_column($min_date,'reserve_date'); $min_date = array_unique($min_date); $time_arr = []; $res = self::find()->where(['mall_id' => $mall_id,'reserve_sku_id' => $reserve_sku_ids]) ->with('timeSpec') ->andWhere(['>=','reserve_date',date('Y-m-d')]) //->andWhere(['in','reserve_date',$min_date]) ->orderBy('reserve_date asc') ->asArray()->all(); $now = time(); if($res){ foreach($res as $val){ $date = $val['reserve_date']; $date = self::getWeekDay($date); if($val['timeSpec']){ foreach($val['timeSpec'] as $k => $v){ $spec_time = explode('-',$v['spec_time']); $start_date_time = $val['reserve_time'].' '.$spec_time[0].':00'; $end_date_time = $val['reserve_time'].' '.$spec_time[1].':00'; $start_time = strtotime($start_date_time); $end_time = strtotime($end_date_time); if($now >= $end_time){ continue; }else{ if(!isset($time_arr[$val['reserve_sku_id']])){ if ($now > $start_time && $val['reserve_time'] == date("Y-m-d")) { continue; } $time_arr[$val['reserve_sku_id']] = [ 'time' => $date.' '.$v['spec_time'], 'time_spec_id' => $v['id'], 'time_id' => $v['reserve_time_id'] ]; } break; } } }else{ if(!isset($time_arr[$val['reserve_sku_id']])){ $time_arr[$val['reserve_sku_id']] = [ 'time' => $date, 'time_spec_id' => 0, 'time_id' => $val['id'] ]; } } } } return $time_arr; } public static function getWeekDay($date) { $week_array = ["日", "一", "二", "三", "四", "五", "六"]; $week = date("w", strtotime($date)); $tomorrow = date('Y-m-d',strtotime('+1 day')); if($date == date('Y-m-d',time())){ return '今天'; } if($date == $tomorrow){ return '明天'; } return "周".$week_array[$week]; } }