| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- <?php
- /**
- * 厦门云联储网络科技有限公司
- * https://www.baokuaiyun.com
- * Copyright (c) 2023 爆块云 All rights reserved.
- */
- namespace app\models;
- use Yii;
- use yii\helpers\Json;
- use yii\db\ActiveRecord;
- use yii\behaviors\TimestampBehavior;
- /**
- * This is the model class for table "{{%local_delivery_freight}}".
- *
- * @property integer $is_enable
- * @property integer $level
- * @property string $name
- * @property string $detail
- * @property string $begin_time
- * @property string $end_time
- * @property integer $created_at
- * @property integer $updated_at
- * @property integer $is_delete
- * @property integer $day
- * @property integer $price_type
- * @property integer $order_price_type
- * @property integer $is_scan
- */
- class LocalDeliveryFreight extends \yii\db\ActiveRecord
- {
- const IS_DELETE_YES = 1;//已删除
- const IS_DELETE_NO = 0;//未删除
- const IS_ENABLE_YES = 1;//启用
- const IS_ENABLE_NO = 0;//关闭
-
- const TYPE_LOCAL = 0;//平台自配
- const TYPE_MAIYATIAN = 1;//麦芽田
- const TYPE_STORE_LOCAL = 2;//商城自配
- const PRICE_TYPE_ORDER = 1;//计价规则-按订单
- const PRICE_TYPE_DISTANCE = 0;//计价规则-按距离
- const ORDER_PRICE_TYPE_ORDER = 1;//订单计价规则-百分比
- const ORDER_PRICE_TYPE_DISTANCE = 0;//订单计价规则-金额
- const IS_SCAN_YES = 1;//扫码抢单规则
- const IS_SCAN_NO = 0;//非扫码抢单规则
- /**
- * @inheritdoc
- */
- public static function tableName()
- {
- return '{{%local_delivery_freight}}';
- }
- public function behaviors()
- {
- return [
- [
- 'class' => 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
- ],
- ];
- }
- }
|