quanwei
18 hours ago c441dea81bd86bdfb12dff35821fed51f4cc91c2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
<?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);
    }
}