startTrans(); try { if (SupplierUserModel::checkExist($data['user_name'])) { $this->error = '用户名已存在'; return false; } // 添加供应商 $this->save($data); //添加供应商账号 $SupplierUserModel = new SupplierUserModel; $data['shop_supplier_id'] = $this['shop_supplier_id']; $data['is_super'] = 1; $SupplierUserModel->save($data); (new teamApplyModel())->becomeTeamByAgent($data['referee_id'],70,$data['app_id']); //根据团队人数判断股东 by yj $shareholderModel = new ShareholderApplyModel; $shareholderModel->becomeShareholderByTeam($data['referee_id'], 80, $data['app_id']); $this->commit(); return true; } catch (\Exception $e) { $this->error = $e->getMessage(); $this->rollback(); return false; } } public function getUserName($user_name) { return $this->where('user_name', '=', $user_name)->count(); } //获取店铺信息 public function getDetail($data, $user) { $detail = $this->alias('s')->where(['shop_supplier_id' => $data['shop_supplier_id']]) ->field("name as store_name,shop_supplier_id,logo_id,category_id,server_score,fav_count,user_id,product_sales,address,notice,description") ->with(['logo', 'category']) ->find(); if ($detail) { $detail['logos'] = $detail['logo']?$detail['logo']['file_path']:''; $detail['category_name'] = $detail['category']['name']; unset($detail['logo']); unset($detail['category']); $detail['isfollow'] = 0; $detail['notice'] = empty($detail['notice']) ? '欢迎光临' . $detail['store_name'] . '~' : $detail['notice']; $detail['supplier_user_id'] = (new SupplierUserModel())->where('shop_supplier_id', '=', $detail['shop_supplier_id'])->value('supplier_user_id'); if ($user) { $detail['isfollow'] = (new FavoriteModel) ->where('pid', '=', $data['shop_supplier_id']) ->where('user_id', '=', $user['user_id']) ->where('type', '=', 10) ->count(); } } return $detail; } //获取微店账号信息 public function getAccount($shop_supplier_id, $field = "*") { $detail = $this->where(['shop_supplier_id' => $shop_supplier_id])->field("$field")->find(); return $detail; } //店铺列表 public function supplierList($param) { // 排序规则 $sort = []; if ($param['sortType'] === 'all') { $sort = ['s.create_time' => 'desc']; } else if ($param['sortType'] === 'sales') { $sort = ['product_sales' => 'desc']; } else if ($param['sortType'] === 'score') { $sort = ['server_score' => 'desc']; } $model = $this; if (isset($param['name']) && $param['name']) { $model = $model->where('name', 'like', '%' . $param['name'] . '%'); } if(!empty($param['supplier_type'])){ $model = $model->where('supplier_type', '=', $param['supplier_type']); } if (isset($param['category_id']) && $param['category_id']) { $model = $model->where('category_id', '=', $param['category_id']); } // 查询列表数据 $list = $model->alias('s')->with(['logo', 'category']) ->where('s.is_delete', '=', '0') ->where('s.is_recycle', '=', 0) //->where('s.is_full', '=', 1) ->field("s.shop_supplier_id,s.name,s.fav_count,logo_id,category_id,server_score,product_sales,address,link_phone,longitude,latitude,supplier_type") ->order($sort) ->paginate($param); $product_model = new ProductModel(); foreach ($list as &$v) { $productList = $product_model->with(['image.file']) ->where([ 'shop_supplier_id' => $v['shop_supplier_id'], 'product_status' => 10, 'audit_status' => 10, 'is_delete' => 0 ]) ->order('product_sort asc,product_id desc') ->limit(3) ->field('product_id,product_price,product_name,sales_initial,sales_actual,line_price') ->select(); $v['productList'] = $productList; $v['logos'] = isset($v['logo'])?$v['logo']['file_path']:''; $v['category_name'] = $v['category']['name']; $v['latitude'] = (float)$v['latitude']; $v['longitude'] = (float)$v['longitude']; unset($v['logo']); unset($v['category']); } return $list; } //查询用户申请供应商状态 public static function getStatus($user) { $apply = (new Apply())->where('user_id', '=', $user['user_id']) ->find(); $supplier = (new static())->where('user_id', '=', $user['user_id']) ->where('is_delete', '=', 0) ->count(); $status = 0; if ($user['user_type'] == 2) { if ($supplier) { $status = 2; } else { $status = 3; } } else { if ($apply) { if ($apply['status'] == 0) { $status = 1; } } } return $status; } //店铺列表 public function getLists($shop_supplier_id='') { $model = $this; // 查询列表数据 $list = $model->with(['qyQrcode'])->where('is_delete', '=', '0') ->where('is_recycle', '=', 0) ->select(); if(!empty($list)){ foreach ($list as $key => &$val){ if($val["shop_supplier_id"] == $shop_supplier_id){ $index=$key; } $val["add_group"]="加群"; } } $data["list"]=$list; $data["index"]=empty($index) ? '-1' : $index; return $data; } //店铺列表(简约) public function getListSimple($params = []) { $model = $this; if (!empty($params['keyword'])) { $model = $model->where('name', 'like', '%'. $params['keyword'] .'%'); } return $model->where('is_delete', '=', '0') ->where('is_recycle', '=', 0) ->order(['create_time' => 'desc']) ->paginate($params); } public static function getUserStore($user_id) { $model = new self(); return $model->where('user_id', '=', $user_id) ->where('is_delete', '=', 0) ->where('is_recycle', '=', 0) ->find(); } /** * 获取团购商户列表(用于移动端团购组件) * @param array $param 查询参数 * @return \think\Paginator */ public function getGroupBuyList($param) { // 获取用户经纬度(用于计算距离) $user_latitude = isset($param['latitude']) ? floatval($param['latitude']) : 0; $user_longitude = isset($param['longitude']) ? floatval($param['longitude']) : 0; // 排序规则 $sort = []; $sortType = isset($param['sortType']) ? $param['sortType'] : 'all'; // 初始化排序标志 $needDistanceSort = false; $needPriceSort = false; $needDistanceFilter = false; $needPriceFilter = false; $needCouponFilter = false; $needTopRankedFilter = false; if ($sortType === 'distance') { // 使用子查询计算距离并排序 $sort = ['avg_price' => 'asc']; // 临时字段,实际使用子查询 $needDistanceSort = true; } else if ($sortType === 'price_low' || $sortType === 'price_asc') { // 使用子查询计算人均价格并升序排序 $sort = ['avg_price' => 'asc']; $needPriceSort = true; $priceSortOrder = 'asc'; } else if ($sortType === 'price_high' || $sortType === 'price_desc') { // 使用子查询计算人均价格并降序排序 $sort = ['avg_price' => 'desc']; $needPriceSort = true; $priceSortOrder = 'desc'; } else if ($sortType === 'score') { $sort = ['server_score' => 'desc']; $needDistanceSort = false; } else { $sort = ['s.create_time' => 'desc']; $needDistanceSort = false; } $model = $this; // 分类筛选 if (isset($param['category_id']) && $param['category_id']) { $model = $model->where('category_id', '=', $param['category_id']); } // 城市商户筛选 if (!empty($param['city_supplier_ids'])) { $supplier_ids = is_array($param['city_supplier_ids']) ? $param['city_supplier_ids'] : explode(',', $param['city_supplier_ids']); $model = $model->whereIn('shop_supplier_id', $supplier_ids); } // 最高减价筛选(仅看有券) if (isset($param['has_coupon']) && $param['has_coupon'] == 1) { $needCouponFilter = true; } // 好评榜筛选(前10名) if (isset($param['top_ranked']) && $param['top_ranked'] == 1) { $needTopRankedFilter = true; } // 最低评分筛选 $minScore = isset($param['min_score']) ? floatval($param['min_score']) : 0; // 只在明确设置了评分限制时才进行筛选 if (isset($param['min_score']) && $minScore > 0) { $model = $model->where('server_score', '>=', $minScore); } // 价格范围筛选 - 改为前置筛选,使用子查询 $priceMin = isset($param['price_min']) ? floatval($param['price_min']) : 0; $priceMax = isset($param['price_max']) ? floatval($param['price_max']) : -1; // 只有当价格参数有效时才进行筛选 if ((isset($param['price_min']) && $priceMin > 0) || (isset($param['price_max']) && $priceMax > 0)) { $needPriceFilter = true; } // 最大距离筛选 $maxDistance = isset($param['max_distance']) ? floatval($param['max_distance']) : 0; // 只在明确设置了距离限制时才进行筛选 if (isset($param['max_distance']) && $maxDistance > 0) { $needDistanceFilter = true; } // 获取用户经纬度(用于计算距离) $user_latitude = isset($param['latitude']) ? floatval($param['latitude']) : 0; $user_longitude = isset($param['longitude']) ? floatval($param['longitude']) : 0; // 构建基础查询 $baseQuery = $model->alias('s') ->with(['logo', 'category']) ->where('s.supplier_type',20) ->where('s.is_delete', '=', '0') ->where('s.is_recycle', '=', 0); // 添加评分排名子查询(用于好评榜筛选) if ($needTopRankedFilter) { // 先获取按评分排序的商户列表,获取前N名的ID $rankSubQuery = $this->alias('s') ->field('shop_supplier_id') ->where('s.is_delete', '=', '0') ->where('s.is_recycle', '=', 0); // 应用分类筛选 if (isset($param['category_id']) && $param['category_id']) { $rankSubQuery = $rankSubQuery->where('category_id', '=', $param['category_id']); } // 应用城市商户筛选 if (!empty($param['city_supplier_ids'])) { $supplier_ids = is_array($param['city_supplier_ids']) ? $param['city_supplier_ids'] : explode(',', $param['city_supplier_ids']); $rankSubQuery = $rankSubQuery->whereIn('shop_supplier_id', $supplier_ids); } $rankSubQuery = $rankSubQuery ->order(['server_score' => 'desc', 'product_sales' => 'desc', 'create_time' => 'asc']) ->limit(10) // 好评榜前10 ->buildSql(); // 在基础查询中添加对排名子查询的限制 $baseQuery = $baseQuery->join([$rankSubQuery => 'rank_top'], 's.shop_supplier_id = rank_top.shop_supplier_id', 'INNER'); } // 添加优惠券筛选子查询 if ($needCouponFilter) { // 检查是否存在全平台通用优惠券(shop_supplier_id = 0) $platformCouponCount = \app\common\model\plus\coupon\Coupon::where('shop_supplier_id', '=', 0) ->where('is_delete', '=', 0) ->where(function ($query) { // 领取后生效的优惠券 $query->whereOr('expire_type', '=', 10); // 或者固定时间且未过期的优惠券 $query->whereOr(function ($q) { $q->where('expire_type', '=', 20) ->where('end_time', '>=', time() - 86400); }); }) ->where(function ($query) { // 数量不限制或者还有剩余 $query->whereOr('total_num', '=', -1); $query->whereOr(function ($q) { $q->whereRaw('receive_num < total_num'); }); }) ->count(); $hasPlatformCoupons = $platformCouponCount > 0; if ($hasPlatformCoupons) { // 如果存在全平台通用优惠券,则所有商户都符合条件,不需要额外筛选 // 保持baseQuery不变,所有商户都能通过筛选 } else { // 如果没有全平台通用优惠券,则只筛选有自己专属优惠券或参与其他商户优惠券活动的商户 // 注意:商户可以参加其他商户发起的优惠券活动,因此需要更精确的逻辑 // 创建子查询获取所有有有效优惠券的商户(包括自己发起的和其他商户发起但本商户参与的) $couponSubQuery = \app\common\model\plus\coupon\Coupon::alias('c') ->field('DISTINCT shop_supplier_id') ->where('c.is_delete', '=', 0) ->where(function ($query) { // 领取后生效的优惠券 $query->whereOr('expire_type', '=', 10); // 或者固定时间且未过期的优惠券 $query->whereOr(function ($q) { $q->where('expire_type', '=', 20) ->where('end_time', '>=', time() - 86400); }); }) ->where(function ($query) { // 数量不限制或者还有剩余 $query->whereOr('total_num', '=', -1); $query->whereOr(function ($q) { $q->whereRaw('receive_num < total_num'); }); }) ->buildSql(); // 在基础查询中添加对优惠券子查询的限制 $baseQuery = $baseQuery->join([$couponSubQuery => 'coupon_valid'], 's.shop_supplier_id = coupon_valid.shop_supplier_id', 'INNER'); } } // 查询列表数据 if ($needPriceSort || $needPriceFilter) { // 使用子查询计算人均价格并排序或筛选 $subQuery = \app\common\model\order\Order::alias('o') ->field('shop_supplier_id, AVG(pay_price) as avg_price') ->where('pay_status', '=', 20) // 已支付 ->where('order_status', '=', 30) // 已完成 ->where('is_delete', '=', 0) ->group('shop_supplier_id') ->buildSql(); // 添加评论数量子查询 $commentSubQuery = \app\common\model\product\Comment::alias('c') ->field('shop_supplier_id, COUNT(*) as comment_count') ->where('status', '=', 1) // 已审核通过的评论 ->where('is_delete', '=', 0) ->group('shop_supplier_id') ->buildSql(); $listRaw = $baseQuery ->join([$subQuery => 'avg_sub'], 's.shop_supplier_id = avg_sub.shop_supplier_id', 'LEFT') ->join([$commentSubQuery => 'comment_count_sub'], 's.shop_supplier_id = comment_count_sub.shop_supplier_id', 'LEFT') ->field("s.shop_supplier_id,s.supplier_type,s.name as supplier_name,s.fav_count,logo_id,category_id,server_score,product_sales,address,link_phone,longitude,latitude,supplier_type, COALESCE(avg_sub.avg_price, 0) as avg_price, COALESCE(comment_count_sub.comment_count, 0) as comment_count") ->with(['logo', 'category']); // 添加价格范围筛选条件 if ($needPriceFilter) { if ($priceMin > 0) { $listRaw = $listRaw->where('avg_sub.avg_price', '>=', $priceMin); } if ($priceMax > 0) { $listRaw = $listRaw->where('avg_sub.avg_price', '<=', $priceMax); } } $listRaw = $listRaw->order('avg_sub.avg_price ' . ($priceSortOrder ?? 'desc') . ', s.create_time desc') ->paginate($param); } else if ($needDistanceSort) { // 添加评论数量子查询 $commentSubQuery = \app\common\model\product\Comment::alias('c') ->field('shop_supplier_id, COUNT(*) as comment_count') ->where('status', '=', 1) // 已审核通过的评论 ->where('is_delete', '=', 0) ->group('shop_supplier_id') ->buildSql(); // 使用子查询计算距离并排序(需要数据库支持地理函数) $listRaw = $baseQuery ->join([$commentSubQuery => 'comment_count_sub'], 's.shop_supplier_id = comment_count_sub.shop_supplier_id', 'LEFT') ->field("s.shop_supplier_id,s.supplier_type,s.name as supplier_name,s.fav_count,logo_id,category_id,server_score,product_sales,address,link_phone,longitude,latitude,supplier_type, IF(s.latitude > 0 AND s.longitude > 0, " . $user_latitude . ", 99999) as dist_sort, COALESCE(comment_count_sub.comment_count, 0) as comment_count") ->with(['logo', 'category']) ->order('dist_sort asc, s.create_time desc') ->paginate($param); } else { // 添加评论数量子查询 $commentSubQuery = \app\common\model\product\Comment::alias('c') ->field('shop_supplier_id, COUNT(*) as comment_count') ->where('status', '=', 1) // 已审核通过的评论 ->where('is_delete', '=', 0) ->group('shop_supplier_id') ->buildSql(); // 普通查询 $listRaw = $baseQuery ->join([$commentSubQuery => 'comment_count_sub'], 's.shop_supplier_id = comment_count_sub.shop_supplier_id', 'LEFT') ->field("s.shop_supplier_id,s.supplier_type,s.name as supplier_name,s.fav_count,logo_id,category_id,server_score,product_sales,address,link_phone,longitude,latitude,supplier_type, COALESCE(comment_count_sub.comment_count, 0) as comment_count") ->order($sort) ->paginate($param); } // 计算评分排名:先查询所有符合条件商户的评分 $rankModel = $this; if (isset($param['category_id']) && $param['category_id']) { $rankModel = $rankModel->where('category_id', '=', $param['category_id']); } if (!empty($param['city_supplier_ids'])) { $supplier_ids = is_array($param['city_supplier_ids']) ? $param['city_supplier_ids'] : explode(',', $param['city_supplier_ids']); $rankModel = $rankModel->whereIn('shop_supplier_id', $supplier_ids); } // 获取所有商户的评分排名(按评分降序) $allSuppliers = $rankModel ->where('is_delete', '=', '0') ->where('is_recycle', '=', 0) ->where('supplier_type', '=', 20) ->field('shop_supplier_id,server_score,product_sales') ->order(['server_score' => 'desc', 'product_sales' => 'desc', 'create_time' => 'asc']) ->select() ->toArray(); // 构建评分排名映射表 $rankMap = []; foreach ($allSuppliers as $index => $supplier) { $rankMap[$supplier['shop_supplier_id']] = $index + 1; } // 获取商品模型 $product_model = new ProductModel(); // 将集合转为数组 $listData = $listRaw->toArray(); foreach ($listData['data'] as &$v) { // 获取商户的团购商品列表(最多3个) $productList = $product_model->with(['image.file']) ->where([ 'shop_supplier_id' => $v['shop_supplier_id'], 'product_status' => 10, 'audit_status' => 10, 'is_delete' => 0 ]) ->order('product_sort asc,product_id desc') ->limit($param['product_num']) ->field('product_id,product_price,product_name,sales_initial,sales_actual,line_price') ->select(); // 格式化商品数据 $v['productList'] = []; foreach ($productList as $product) { // 计算该商品可用的最高优惠券减价 $product_reduce = $this->calculateProductReducePrice( $v['shop_supplier_id'], $product['product_id'], $product['product_price'] ); $v['productList'][] = [ 'product_id' => $product['product_id'], 'product_name' => $product['product_name'], 'product_image' => isset($product['image'][0]['file']['file_path']) ? $product['image'][0]['file']['file_path'] : '', 'product_price' => $product['product_price'], 'line_price' => $product['line_price'], 'reduce_price' => $product_reduce, // 根据优惠券计算商品减价 ]; } // 使用子查询返回的人均价格(如果存在) $average_price = isset($v['avg_price']) && $v['avg_price'] > 0 ? round($v['avg_price'], 2) : $this->calculateAverageConsumption($v['shop_supplier_id']); // 计算与用户的距离 $distance = $this->calculateDistance( $user_latitude, $user_longitude, floatval($v['latitude']), floatval($v['longitude']) ); // 计算最高减价:根据商户优惠券 $max_reduce_price = $this->calculateMaxReducePrice($v['shop_supplier_id']); // 商户信息格式化 $v['logo_image'] = isset($v['logo']) ? $v['logo']['file_path'] : ''; $v['category_name'] = isset($v['category']) ? $v['category']['name'] : ''; $v['latitude'] = (float)$v['latitude']; $v['longitude'] = (float)$v['longitude']; // 模拟团购数据(根据实际业务调整) $v['server_score'] = $v['server_score'] ?: 4.8; $v['server_score_text'] = ''; if($v['server_score'] >= 4.0 && $v['server_score'] < 4.5){ $v['server_score_text'] = '优秀'; } else if($v['server_score'] >= 4.5 && $v['server_score'] < 4.8){ $v['server_score_text'] = '非常棒'; } else if($v['server_score'] >= 4.8){ $v['server_score_text'] = ' 超赞'; } $v['comment'] = $v['fav_count'] ?: 0; $v['comment_count'] = isset($v['comment_count']) ? $v['comment_count'] : 0; // 评论数量 $v['average_price'] = $average_price; // 人均消费,根据历史订单计算 $v['distance'] = $distance; // 距离,根据经纬度计算 $v['max_reduce_price'] = $max_reduce_price; // 最高减价,根据优惠券计算 // 根据评分获取排名 $v['ranking'] = isset($rankMap[$v['shop_supplier_id']]) ? $rankMap[$v['shop_supplier_id']] : 999; // 存储距离的数值用于排序 $v['distance_value'] = $this->parseDistanceValue($distance); unset($v['logo']); unset($v['category']); } // 后置筛选 - 现在只需要处理不需要子查询的筛选 $filteredData = []; foreach ($listData['data'] as $item) { // 距离筛选 if (isset($needDistanceFilter) && $needDistanceFilter === true) { $distanceKm = $item['distance_value']; if ($distanceKm > $maxDistance) continue; } $filteredData[] = $item; } $listData['data'] = $filteredData; // 距离排序仍然在PHP中处理(因为距离计算涉及复杂公式) if ($needDistanceSort) { usort($listData['data'], function($a, $b) { return $a['distance_value'] <=> $b['distance_value']; }); // 重新分页 $page = isset($param['page']) ? intval($param['page']) : 1; $pageSize = isset($param['list_rows']) ? intval($param['list_rows']) : 10; $offset = ($page - 1) * $pageSize; $listData['total'] = count($listData['data']); $listData['data'] = array_slice($listData['data'], $offset, $pageSize); } // 更新分页数据 $list = $listData; return $list; } /** * 计算商户的人均消费 * @param int $shop_supplier_id 商户ID * @return float 人均消费金额 */ private function calculateAverageConsumption($shop_supplier_id) { // 查询商户的已完成订单(已支付且非退款) $orderModel = \app\common\model\order\Order::where('shop_supplier_id', '=', $shop_supplier_id) ->where('pay_status', '=', 20) // 已支付 ->where('order_status', '=', 30) // 已完成 ->where('is_delete', '=', 0) ->field('order_id, pay_price, user_id') ->select(); if ($orderModel->isEmpty()) { // 没有订单,返回默认值 return 0; } // 计算总金额和总人数(去重用户) $totalAmount = 0; $userIds = []; foreach ($orderModel as $order) { $totalAmount += $order['pay_price']; $userIds[] = $order['user_id']; } // 去重用户数量 $uniqueUsers = array_unique($userIds); $userCount = count($uniqueUsers); // 计算人均消费 if ($userCount > 0) { $averagePrice = round($totalAmount / $userCount, 2); return $averagePrice > 0 ? $averagePrice : 0; } return 0; } /** * 计算两点之间的距离(根据经纬度) * @param float $lat1 用户纬度 * @param float $lon1 用户经度 * @param float $lat2 商户纬度 * @param float $lon2 商户经度 * @return string 格式化后的距离字符串(如:"1.2km" 或 "500m") */ private function calculateDistance($lat1, $lon1, $lat2, $lon2) { // 如果没有用户位置或商户位置,返回默认值 if (empty($lat1) || empty($lon1) || empty($lat2) || empty($lon2)) { return '--'; } // 地球半径(千米) $earthRadius = 6371; // 将角度转为弧度 $lat1Rad = deg2rad($lat1); $lon1Rad = deg2rad($lon1); $lat2Rad = deg2rad($lat2); $lon2Rad = deg2rad($lon2); // 计算纬度和经度的差值 $latDiff = $lat2Rad - $lat1Rad; $lonDiff = $lon2Rad - $lon1Rad; // Haversine公式计算距离 $a = sin($latDiff / 2) * sin($latDiff / 2) + cos($lat1Rad) * cos($lat2Rad) * sin($lonDiff / 2) * sin($lonDiff / 2); $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); $distance = $earthRadius * $c; // 格式化距离 if ($distance < 1) { // 小于1千米,显示为米 return round($distance * 1000) . 'm'; } else if ($distance < 10) { // 1-10千米,保留一位小数 return round($distance, 1) . 'km'; } else { // 大于10千米,只显示整数 return round($distance) . 'km'; } } /** * 解析距离字符串返回数值(用于排序) * @param string $distanceStr 距离字符串(如:"1.2km" 或 "500m") * @return float 距离数值(千米) */ private function parseDistanceValue($distanceStr) { if (empty($distanceStr) || $distanceStr === '--') { return 99999; } $value = 0; if (strpos($distanceStr, 'km') !== false) { $value = floatval(str_replace('km', '', $distanceStr)); } else if (strpos($distanceStr, 'm') !== false) { $value = floatval(str_replace('m', '', $distanceStr)) / 1000; } return $value; } /** * 计算商户的最高减价(根据优惠券) * @param int $shop_supplier_id 商户ID * @return float 最高减价金额 */ private function calculateMaxReducePrice($shop_supplier_id) { // 查询商户的有效优惠券(未删除、未过期、未被领完) $couponModel = \app\common\model\plus\coupon\Coupon::where('shop_supplier_id', 'in', [$shop_supplier_id,0]) ->where('is_delete', '=', 0) ->where(function ($query) { // 领取后生效的优惠券 $query->whereOr('expire_type', '=', 10); // 或者固定时间且未过期的优惠券 $query->whereOr(function ($q) { $q->where('expire_type', '=', 20) ->where('end_time', '>=', time() - 86400); }); }) ->where(function ($query) { // 数量不限制或者还有剩余 $query->whereOr('total_num', '=', -1); $query->whereOr(function ($q) { $q->whereRaw('receive_num < total_num'); }); }) ->field('coupon_id, coupon_type, reduce_price, discount,total_num,expire_type,receive_num,end_time') ->select(); if ($couponModel->isEmpty()) { // 没有优惠券,返回0 return 0; } $maxReduce = 0; foreach ($couponModel as $coupon) { // 满减券:直接取减免金额 if ($coupon['coupon_type']['value'] == 10) { if ($coupon['reduce_price'] > $maxReduce) { $maxReduce = $coupon['reduce_price']; } } // 折扣券:按照一定基准价计算(假设100元的基准) else if ($coupon['coupon_type']['value'] == 20) { $basePrice = 100; // 基准价格 $discountRate = $coupon['discount'] / 10; // 折扣率(如8.5折) $reduceAmount = $basePrice * (1 - $discountRate / 10); if ($reduceAmount > $maxReduce) { $maxReduce = $reduceAmount; } } } // 返回整数 return intval($maxReduce); } /** * 计算商品的优惠券减价 * @param int $shop_supplier_id 商户ID * @param int $product_id 商品ID * @param float $product_price 商品价格 * @return float 减价金额 */ private function calculateProductReducePrice($shop_supplier_id, $product_id, $product_price) { // 查询商户的有效优惠券 $couponModel = \app\common\model\plus\coupon\Coupon::where('shop_supplier_id', 'in', [$shop_supplier_id,0]) ->where('is_delete', '=', 0) ->where(function ($query) { // 领取后生效的优惠券 $query->whereOr('expire_type', '=', 10); // 或者固定时间且未过期的优惠券 $query->whereOr(function ($q) { $q->where('expire_type', '=', 20) ->where('end_time', '>=', time() - 86400); }); }) ->where(function ($query) { // 数量不限制或者还有剩余 $query->whereOr('total_num', '=', -1); $query->whereOr(function ($q) { $q->whereRaw('receive_num < total_num'); }); }) ->field('coupon_id, coupon_type, reduce_price, discount, min_price, apply_range, product_ids, category_ids') ->select(); if ($couponModel->isEmpty()) { return 0; } $maxReduce = 0; foreach ($couponModel as $coupon) { // 检查优惠券的适用范围 $isApplicable = false; // 10-全部商品 if ($coupon['apply_range'] == 10) { $isApplicable = true; } // 20-指定商品 else if ($coupon['apply_range'] == 20 && !empty($coupon['product_ids'])) { $productIds = json_decode($coupon['product_ids'], true); if (is_array($productIds) && in_array($product_id, $productIds)) { $isApplicable = true; } } // 30-指定分类(需要查询商品分类,这里简化处理,默认不适用) else if ($coupon['apply_range'] == 30) { // 可以后续扩展分类判断逻辑 $isApplicable = false; } if (!$isApplicable) { continue; } // 计算减免金额 $reduceAmount = 0; // 满减券 if ($coupon['coupon_type']['value'] == 10) { // 检查是否达到最低消费金额 if ($product_price >= $coupon['min_price']) { $reduceAmount = $coupon['reduce_price']; } } // 折扣券 else if ($coupon['coupon_type']['value'] == 20) { $discountRate = $coupon['discount'] / 10; // 折扣率 $reduceAmount = $product_price * (1 - $discountRate / 10); } if ($reduceAmount > $maxReduce) { $maxReduce = $reduceAmount; } } // 返回整数 return intval($maxReduce); } }