<?php
|
|
namespace app\api\model\supplier;
|
|
use app\common\model\plus\shareholder\Apply as ShareholderApplyModel;
|
use app\common\model\supplier\Supplier as SupplierModel;
|
use app\common\model\supplier\User as SupplierUserModel;
|
use app\api\model\user\Favorite as FavoriteModel;
|
use app\api\model\product\Product as ProductModel;
|
use app\api\model\plus\team\Apply as teamApplyModel;
|
/**
|
* 供应商模型类
|
*/
|
class Supplier extends SupplierModel
|
{
|
/**
|
* 添加
|
*/
|
public function addData($data)
|
{
|
// 开启事务
|
$this->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);
|
}
|
}
|