TimestampBehavior::class, 'attributes' => [ ActiveRecord::EVENT_BEFORE_INSERT => ['updated_at', 'created_at'], ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at' ] ] ]; } /** * @inheritdoc */ public function rules() { return [ [['is_enable', 'level', 'is_delete', 'day', 'type', 'store_id', 'price_type', 'order_price_type', 'is_scan'], 'integer'], [['name'], 'string', 'max' => 255], [['detail', 'begin_time','end_time'], 'string'], ]; } /** * @inheritdoc */ public function attributeLabels() { return [ 'id' => 'ID', 'is_enable' => '是否启用:0=否,1=是', 'type' => '配送方式;0:平台自配 1:麦芽田', 'level' => '规则优先级,值越大优先级越高', 'name' => '名称', 'detail' => '规则详细', 'begin_time' => '开始时间段', 'end_time' => '结束时间段', 'created_at' => '创建时间', 'updated_at' => '最后一次修改时间', 'is_delete' => '是否删除:0=否;1=是;', 'day' => '可预约天数', 'price_type' => '计价规则 1 = 按订单 0 = 按距离', 'order_price_type' => '订单计价规则 1百分比 0金额', 'is_scan' => '是否为扫码抢单规则' ]; } //$is_front_delivery 仓库配送单 public static function getFreight($store_id, $address, $delivery_time, $type = 0, $goods_list = [], $is_scan = LocalDeliveryFreight::IS_SCAN_NO, $is_front_delivery = DeliveryInfo::IS_FRONT_DELIVERY_NO, $front_agent_admin_id = 0) { $store = Store::findOne($store_id); $latitude = $store->latitude; $longitude = $store->longitude; //取货地址 if ($is_front_delivery) { $front_agent = Admin::findOne($front_agent_admin_id); $latitude = $front_agent->lat ?: 0; $longitude = $front_agent->lng ?: 0; } //收货地址 if(!is_object($address)){ $address = (object)($address); } //距离(单位:km) $distance_str = \app\utils\Tools::getDistance($latitude, $longitude, $address->latitude, $address->longitude); if (strpos($distance_str, 'km') !== false) { // 如果包含 'km' 则将字符串转换为浮点数并乘以 1000 $distance = (float) str_replace('km', '', $distance_str) * 1000; } elseif (strpos($distance_str, 'm') !== false) { // 如果包含 'm' 则将字符串转换为整数 $distance = (int) str_replace('m', '', $distance_str); } $distance = bcdiv($distance,1000,2); //配送时间戳 $delivery_time_stamp = strtotime($delivery_time) ?: time(); //获取同城配送的计价规则 // 构建查询对象 $query = LocalDeliveryFreight::find() ->where(['is_enable' => 1, 'is_delete' => 0]) ->orderBy(['level' => SORT_DESC]); if(in_array($type, [self::TYPE_MAIYATIAN, self::TYPE_STORE_LOCAL])){ $query->andWhere(['store_id' => $store_id]); } if(in_array($type, [self::TYPE_LOCAL, self::TYPE_STORE_LOCAL])){ $query->andWhere(['type' => self::TYPE_LOCAL]); } if($type == self::TYPE_LOCAL){ $query->andWhere(['store_id' => 0]); } if($type == self::TYPE_MAIYATIAN){ $query->andWhere(['type' => self::TYPE_MAIYATIAN]); } if ($is_scan == self::IS_SCAN_YES) { $query->andWhere(['is_scan' => self::IS_SCAN_YES]); } // 获取所有数据 $data = $query->asArray()->all(); // 过滤出符合条件的数据 $filteredData = []; foreach ($data as $item) { $hour = strtotime(date('H:i',$delivery_time_stamp));//实际 $beginTime = strtotime($item['begin_time']);//开始 $endTime = strtotime($item['end_time']);//结束 if ($beginTime <= $endTime) { // 普通时间段,直接判断时间是否在范围内 if ($hour >= $beginTime && $hour <= $endTime) { $filteredData[] = $item; break; } } else { // 跨越日期的时间段,第一个条件范围是当日的开始时间和次日的结束时间例如:当日23:00至次日5:00,第二个条件为次日的开始时间例如:次日23:00,$delivery_time_stamp的取值范围为当前时间到次日的24点,所以要考虑次日的开始时间。 if (($delivery_time_stamp >= $beginTime && $delivery_time_stamp <= $endTime+86400) || $delivery_time_stamp >= $beginTime+86400) { $filteredData[] = $item; break; } } } // 获取最终结果(根据需求自行处理) if (!empty($filteredData)) { $result = $filteredData[0]; // 这里只取第一条符合条件的数据作为示例 $freight_detail = json_decode($result['detail'],true)[0]; //配送费计算 $freight = 0; if (intval($result['price_type'])) { $total_price = 0; foreach ($goods_list as $goods) { $total_price += ($goods['price']);//$goods['num'] * } if (intval($result['order_price_type'])) { $freight = sprintf('%.2f', ($total_price * ($freight_detail['distance_price'] / 100))); } else { $freight = $freight_detail['distance_price']; } } else { if($distance <= $freight_detail['distance']) { $freight = $freight_detail['distance_price']; } else { $freight = bcadd($freight_detail['distance_price'],bcmul(ceil(bcdiv(bcsub($distance,$freight_detail['distance'],2),$freight_detail['second'],2)),$freight_detail['second_price'],2),2); } } }else{ $freight = 100; return [ 'code' => 1, 'msg' => '配送计价规则匹配错误,请稍后重试', ]; } return [ 'code' => 0, 'data' => (float)$freight, 'info' => [ 'resultcode' => 0, 'address' => $address, 'store' => $store, 'distance' => $distance, 'delivery_time' => $delivery_time, 'delivery_time_stamp' => $delivery_time_stamp, 'LocalDeliveryFreight' => $result, 'freight_detail' => $freight_detail, 'fee' => (float)$freight, 'endTime' => $endTime ], ]; } }