Explorar el Código

[智价云] 违规处理展示信息更新

tangyuanwang hace 1 día
padre
commit
d622d639d4

+ 292 - 24
app/Http/Controllers/Manager/Process/LowPriceGoods.php

@@ -7,6 +7,10 @@ use App\Http\Requests\Manager\Process\LowPriceGoods as Request;
 use App\Models\Manager\Process\LowPriceGoods as LowPriceGoodsModel;
 use App\Jobs\Manager\Process\LowPriceGoodsJobs;
 use App\Models\Manager\Personnel\Employee as EmployeeModel;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use PhpOffice\PhpSpreadsheet\Style\Alignment;
+use App\Models\Manager\Process\LowPriceGoodsMember as LowPriceGoodsMemberModel;
 
 /**
  * 违规处理-低价商品
@@ -24,7 +28,7 @@ class LowPriceGoods extends Controller
      * @date      2025-12-08
      * 
      */
-    public function list(Request $request, LowPriceGoodsModel $LowPriceGoodsModel,EmployeeModel $EmployeeModel)
+    public function list(Request $request, LowPriceGoodsModel $LowPriceGoodsModel, EmployeeModel $EmployeeModel,LowPriceGoodsMemberModel $LowPriceGoodsMemberModel)
     {
         $request->scene('list')->validate();
         // 查询条件
@@ -34,40 +38,94 @@ class LowPriceGoods extends Controller
         $start_time = request('start_time', '');
         $end_time = request('end_time', '');
         $product_name = request('product_name', '');
+        $product_names = request('product_names', '');
         $first_responsible_person = request('first_responsible_person', '');
         $responsible_person = request('responsible_person', '');
         $platform = request('platform', '');
         $company_name = request('company_name', '');
         $store_name = request('store_name', '');
+        $store_names = request('store_names', '');
         $source_responsible_person = request('source_responsible_person', '');
         $processing_status = request('processing_status', '');
-        $product_name = request('product_name', '');
         $product_specs = request('product_specs', '');
         $online_posting_cunt = request('online_posting_cunt', '');
         // 时间条件
         if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
         if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
         // 其他条件
-        if ($status) $map[] = ['status', '=', $status];
         if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+        if ($store_name) $map[]   = ['store_name','like',"%$store_name%"];
 
-        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
-        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
-        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
-        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
-        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
-        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
-        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
-        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
-        if ($product_specs) $map[] = ['product_specs', 'like', "%$product_specs%"];
-        if ($online_posting_cunt) $map[] = ['online_posting_cunt', '=', $online_posting_cunt];
-        // 查询数据
-        $result = $LowPriceGoodsModel->query()
+        //多选平台查询
+        if($platform && is_string($platform)){
+            $platform = explode(',', $platform);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('platform', $platform);
+        }
+        //多选处理状态查询
+        if($processing_status && is_string($processing_status)){
+            $processing_status = explode(',', $processing_status);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('processing_status', $processing_status);
+        }
+        //多选状态查询
+        if($status && is_string($status)){
+            $status = explode(',', $status);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('status', $status);
+        }
+        //多选店铺名称查询
+        if($store_names && is_string($store_names)){
+            $store_names = explode(',', $store_names);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('store_name', $store_names);
+        }
+        //多选违规挂网次数查询
+        if($online_posting_cunt && is_string($online_posting_cunt)){
+            $online_posting_cunt = explode(',', $online_posting_cunt);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('online_posting_cunt', $online_posting_cunt);
+        }
+        //多选规格查询
+        if($product_specs && is_string($product_specs)){
+            $product_specs = explode(',', $product_specs);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('product_specs', $product_specs);
+        }
+        //多选商品查询
+        if ($product_names && is_string($product_names)) {
+            $product_names = explode(',', $product_names);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('product_name', $product_names);
+        }
+        //多选公司查询
+        if ($company_name && is_string($company_name)) {
+            $company_name = explode(',', $company_name);
+            $LowPriceGoodsModel=$LowPriceGoodsModel->whereIn('company_name', $company_name);
+        }
+        //多选第一责任人
+        if ($first_responsible_person && is_string($first_responsible_person)) {
+            $first_responsible_person = explode(',', $first_responsible_person);
+            $subQuery = $LowPriceGoodsMemberModel->whereIn('employee_id', $first_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $LowPriceGoodsModel = $LowPriceGoodsModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选责任人
+        if ($responsible_person && is_string($responsible_person)) {
+            $responsible_person = explode(',', $responsible_person);
+            $subQuery = $LowPriceGoodsMemberModel->whereIn('employee_id', $responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $LowPriceGoodsModel = $LowPriceGoodsModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选溯源责任人
+        if ($source_responsible_person && is_string($source_responsible_person)) {
+            $source_responsible_person = explode(',', $source_responsible_person);
+            $subQuery = $LowPriceGoodsMemberModel->whereIn('employee_id', $source_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $LowPriceGoodsModel = $LowPriceGoodsModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        $result = $LowPriceGoodsModel
             ->where($map)
             ->orderByDesc('id')
             ->paginate($limit)->toarray();
         // 分配数据
-        if (!$result)  return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
+        if (!$result)  json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
         if (isset($result['data']) && count($result['data']) > 0) {
             foreach ($result['data'] as $key => $value) {
                 //查询第一责任人名称
@@ -88,13 +146,223 @@ class LowPriceGoods extends Controller
         return        json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $result]);
     }
 
+
+    /**
+     * 列表导出
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_excel(Request $request, LowPriceGoodsModel $LowPriceGoodsModel, EmployeeModel $EmployeeModel)
+    {
+        $request->scene('export_excel')->validate();
+        // 查询条件
+        $map  = [];
+        $status    = request('status', '');
+        $start_time = request('start_time', '');
+        $end_time = request('end_time', '');
+        $product_name = request('product_name', '');
+        $first_responsible_person = request('first_responsible_person', '');
+        $responsible_person = request('responsible_person', '');
+        $platform = request('platform', '');
+        $company_name = request('company_name', '');
+        $store_name = request('store_name', '');
+        $source_responsible_person = request('source_responsible_person', '');
+        $processing_status = request('processing_status', '');
+        $product_name = request('product_name', '');
+        $product_specs = request('product_specs', '');
+        $online_posting_cunt = request('online_posting_cunt', '');
+        // 时间条件
+        if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
+        if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
+        // 其他条件
+        if ($status) $map[] = ['status', '=', $status];
+        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+
+        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
+        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
+        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
+        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
+        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
+        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
+        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
+        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+        if ($product_specs) $map[] = ['product_specs', 'like', "%$product_specs%"];
+        if ($online_posting_cunt) $map[] = ['online_posting_cunt', '=', $online_posting_cunt];
+        // 查询数据
+        $result = $LowPriceGoodsModel->query()
+            ->where($map)
+            ->orderByDesc('id')->get()->toarray();
+        // 分配数据
+        if (!$result)  return json_send(['code' => 'error', 'msg' => '暂无数据']);
+        // 处理责任人展示信息
+        $list_data = $this->processing_responsible_person($result);
+        // 导出数据
+        $this->export_download($list_data);
+    }
+
+
+    /**
+     * 处理责任人展示信息
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-12-17
+     */
+    public function processing_responsible_person($result)
+    {
+        $EmployeeModel = new EmployeeModel();
+        //获取所有员工
+        $employeee_data = $EmployeeModel->select(['id', 'name'])->get()->toarray();
+        $employeee_list = [];
+        if (!empty($employeee_data)) {
+            foreach ($employeee_data as $key => $value) {
+                $employeee_list[$value['id']] = $value['name'];
+            }
+        }
+        if (isset($result) && count($result) > 0) {
+            foreach ($result as $key => $value) {
+                //查询第一责任人名称
+                $first_responsible_person = $value['first_responsible_person'] != '' ? explode(',', $value['first_responsible_person']) : [];
+                $first_responsible_person_name = [];
+                if (!empty($first_responsible_person)) {
+                    foreach ($first_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $first_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['first_responsible_person_name'] = $first_responsible_person_name;
+                //查询责任人名称
+                $responsible_person = $value['responsible_person'] != '' ? explode(',', $value['responsible_person']) : [];
+                $responsible_person_name = [];
+                if (!empty($responsible_person)) {
+                    foreach ($responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['responsible_person_name'] = $responsible_person_name;
+                //查询来源责任人名称
+                $source_responsible_person = $value['source_responsible_person'] != '' ? explode(',', $value['source_responsible_person']) : [];
+                $source_responsible_person_name = [];
+                if (!empty($source_responsible_person)) {
+                    foreach ($source_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $source_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['source_responsible_person_name'] = $source_responsible_person_name;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * 导出下载
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_download($data)
+    {
+        // 创建一个新的 Spreadsheet 对象
+        $spreadsheet = new Spreadsheet();
+        $sheet = $spreadsheet->getActiveSheet();
+
+        //合并单元格
+        $sheet->mergeCells('A1:R1');
+        $sheet->setCellValue('A1', '低价挂网商品导出(导出时间:' . date('Y-m-d H:i:s', time()) . ')'); // 设置合并后的单元格内容
+        // 获取合并后的单元格样式对象
+        $style = $sheet->getStyle('A1');
+        // 设置水平居中和垂直居中
+        $style->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setVertical(Alignment::VERTICAL_CENTER);
+        // 然后设置行高以适应两行文本
+        $sheet->getRowDimension(1)->setRowHeight(40); // 设置行高,单位是磅(point)
+        // 设置表头
+        $sheet->setCellValue('A2', '第一责任人');
+        $sheet->setCellValue('B2', '责任人');
+        $sheet->setCellValue('C2', '平台');
+        $sheet->setCellValue('D2', '商品名称');
+        $sheet->setCellValue('E2', '商品规格');
+        $sheet->setCellValue('F2', '指导价');
+        $sheet->setCellValue('G2', '挂网价格');
+        $sheet->setCellValue('H2', '挂网次数');
+        $sheet->setCellValue('I2', '链接地址');
+        $sheet->setCellValue('J2', '店铺名称');
+        $sheet->setCellValue('K2', '公司名称');
+        $sheet->setCellValue('L2', '信用代码');
+        $sheet->setCellValue('M2', '省份');
+        $sheet->setCellValue('N2', '城市');
+        $sheet->setCellValue('O2', '溯源责任人');
+        $sheet->setCellValue('P2', '处理状态');
+        $sheet->setCellValue('Q2', '任务状态');
+        $sheet->setCellValue('R2', '记录时间');
+
+        $platform_data = [
+            '0' => '全部',
+            '1' => '淘宝',
+            '2' => '京东',
+            '3' => '拼多多',
+            '4' => '美团',
+            '5' => '药师帮',
+            '6' => '1药城',
+            '7' => '药久久',
+        ];
+        $processing_status_text = [
+            '1' => '待处理',
+        ];
+        $status_text = [
+            '0' => '有效',
+            '1' => '无效',
+        ];
+        // 填充数据
+        $row = 3; // 从第2行开始
+        foreach ($data as $item) {
+            $first_responsible_person_name = !empty($item['first_responsible_person_name']) ? implode(',', $item['first_responsible_person_name']) : '';
+            $responsible_person_name = !empty($item['responsible_person_name']) ? implode(',', $item['responsible_person_name']) : '';
+            $source_responsible_person_name = !empty($item['source_responsible_person_name']) ? implode(',', $item['source_responsible_person_name']) : '';
+            $sheet->setCellValue('A' . $row, $first_responsible_person_name);
+            $sheet->setCellValue('B' . $row, $responsible_person_name);
+            $sheet->setCellValue('C' . $row, isset($platform_data[$item['platform']]) ? $platform_data[$item['platform']] : '');
+            $sheet->setCellValue('D' . $row, $item['product_name']);
+            $sheet->setCellValue('E' . $row, $item['product_specs']);
+            $sheet->setCellValue('F' . $row, $item['suggested_price']);
+            $sheet->setCellValue('G' . $row, $item['online_posting_price']);
+            $sheet->setCellValue('H' . $row, $item['online_posting_cunt']);
+            $sheet->setCellValue('I' . $row, $item['link_url']);
+            $sheet->setCellValue('J' . $row, $item['store_name']);
+            $sheet->setCellValue('K' . $row, $item['company_name']);
+            $sheet->setCellValue('L' . $row, $item['social_credit_code']);
+            $sheet->setCellValue('M' . $row, $item['province_name']);
+            $sheet->setCellValue('N' . $row, $item['city_name']);
+            $sheet->setCellValue('O' . $row, $source_responsible_person_name);
+            $sheet->setCellValue('P' . $row, isset($processing_status_text[$item['processing_status']]) ? $processing_status_text[$item['processing_status']] : '');
+            $sheet->setCellValue('Q' . $row, isset($status_text[$item['status']]) ? $status_text[$item['status']] : '');
+            $sheet->setCellValue('R' . $row, date('Y-m-d H:i:s', $item['insert_time']));
+            $row++;
+        }
+        // 生成 Excel 文件
+        $writer = new Xlsx($spreadsheet);
+
+        // 直接输出到浏览器(下载)
+        $filename = '低价挂网商品数据' . date('YmdHis') . '.xlsx';
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+        header('Content-Disposition: attachment;filename="' . $filename . '"');
+        header('Cache-Control: max-age=0');
+        $writer->save('php://output');
+        exit;
+    }
+
+
     /**
      * 详情
      * @author    唐远望
      * @version   1.0
      * @date      2025-12-08
      */
-    public function detail(Request $request, LowPriceGoodsModel $LowPriceGoodsModel,EmployeeModel $EmployeeModel)
+    public function detail(Request $request, LowPriceGoodsModel $LowPriceGoodsModel, EmployeeModel $EmployeeModel)
     {
         $request->scene('detail')->validate();
         // 接收参数
@@ -105,15 +373,15 @@ class LowPriceGoods extends Controller
         //查询第一责任人名称
         $first_responsible_person = explode(',', $data->first_responsible_person);
         $first_responsible_person_name = $EmployeeModel->whereIn('id', $first_responsible_person)->pluck('name')->toarray();
-        $data->first_responsible_person_name= $first_responsible_person_name;
+        $data->first_responsible_person_name = $first_responsible_person_name;
         //查询责任人名称
         $responsible_person = explode(',', $data->responsible_person);
         $responsible_person_name = $EmployeeModel->whereIn('id', $responsible_person)->pluck('name')->toarray();
-        $data->responsible_person_name= $responsible_person_name;
+        $data->responsible_person_name = $responsible_person_name;
         //查询来源责任人名称
         $source_responsible_person = explode(',', $data->source_responsible_person);
         $source_responsible_person_name = $EmployeeModel->whereIn('id', $source_responsible_person)->pluck('name')->toarray();
-        $data->source_responsible_person_name= $source_responsible_person_name;
+        $data->source_responsible_person_name = $source_responsible_person_name;
         // 加载模板
         return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $data]);
     }
@@ -216,7 +484,7 @@ class LowPriceGoods extends Controller
         // 执行修改
         $result            =  $LowPriceGoodsModel->changeProcessingStatus($where, $processing_status);
         // 提示新增失败
-        if (!$result)    return json_send(['code' => 'error', 'msg' => '设置失败']);    
+        if (!$result)    return json_send(['code' => 'error', 'msg' => '设置失败']);
         // 告知结果
         return             json_send(['code' => 'success', 'msg' => '设置成功']);
     }
@@ -254,11 +522,11 @@ class LowPriceGoods extends Controller
      */
     public function data_cleaning(Request $request)
     {
-         // 验证参数
+        // 验证参数
         $request->scene('data_cleaning')->validate();
         $access_token = request('access_token', '');
-        $admin_id=$access_token['uid'];
-        $message_data =['page'=>'1','limit'=>50,'admin_id'=>$admin_id];
+        $admin_id = $access_token['uid'];
+        $message_data = ['page' => '1', 'limit' => 50, 'admin_id' => $admin_id];
         LowPriceGoodsJobs::dispatch($message_data);
         // LowPriceGoodsJobs::dispatchSync($message_data);
         // 告知结果

+ 286 - 18
app/Http/Controllers/Manager/Process/ViolationProduct.php

@@ -7,6 +7,10 @@ use App\Http\Requests\Manager\Process\ViolationProduct as Request;
 use App\Models\Manager\Process\ViolationProduct as ViolationProductModel;
 use App\Jobs\Manager\Process\ViolationProductJobs;
 use App\Models\Manager\Personnel\Employee as EmployeeModel;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use PhpOffice\PhpSpreadsheet\Style\Alignment;
+use App\Models\Manager\Process\ViolationProductMember as ViolationProductMemberModel;
 
 /**
  * 违规处理-违规商品
@@ -24,7 +28,7 @@ class ViolationProduct extends Controller
      * @date      2025-12-08
      * 
      */
-    public function list(Request $request, ViolationProductModel $ViolationProductModel, EmployeeModel $EmployeeModel)
+    public function list(Request $request, ViolationProductModel $ViolationProductModel,EmployeeModel $EmployeeModel,ViolationProductMemberModel $ViolationProductMemberModel)
     {
         $request->scene('list')->validate();
         // 查询条件
@@ -34,40 +38,94 @@ class ViolationProduct extends Controller
         $start_time = request('start_time', '');
         $end_time = request('end_time', '');
         $product_name = request('product_name', '');
+        $product_names = request('product_names', '');
         $first_responsible_person = request('first_responsible_person', '');
         $responsible_person = request('responsible_person', '');
         $platform = request('platform', '');
         $company_name = request('company_name', '');
         $store_name = request('store_name', '');
+        $store_names = request('store_names', '');
         $source_responsible_person = request('source_responsible_person', '');
         $processing_status = request('processing_status', '');
-        $product_name = request('product_name', '');
         $product_specs = request('product_specs', '');
         $online_posting_cunt = request('online_posting_cunt', '');
         // 时间条件
         if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
         if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
         // 其他条件
-        if ($status) $map[] = ['status', '=', $status];
         if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+        if ($store_name) $map[]   = ['store_name','like',"%$store_name%"];
 
-        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
-        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
-        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
-        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
-        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
-        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
-        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
-        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
-        if ($product_specs) $map[] = ['product_specs', 'like', "%$product_specs%"];
-        if ($online_posting_cunt) $map[] = ['online_posting_cunt', '=', $online_posting_cunt];
-        // 查询数据
+        //多选平台查询
+        if($platform && is_string($platform)){
+            $platform = explode(',', $platform);
+            $ViolationProductModel=$ViolationProductModel->whereIn('platform', $platform);
+        }
+        //多选处理状态查询
+        if($processing_status && is_string($processing_status)){
+            $processing_status = explode(',', $processing_status);
+            $ViolationProductModel=$ViolationProductModel->whereIn('processing_status', $processing_status);
+        }
+        //多选状态查询
+        if($status && is_string($status)){
+            $status = explode(',', $status);
+            $ViolationProductModel=$ViolationProductModel->whereIn('status', $status);
+        }
+        //多选店铺名称查询
+        if($store_names && is_string($store_names)){
+            $store_names = explode(',', $store_names);
+            $ViolationProductModel=$ViolationProductModel->whereIn('store_name', $store_names);
+        }
+        //多选违规挂网次数查询
+        if($online_posting_cunt && is_string($online_posting_cunt)){
+            $online_posting_cunt = explode(',', $online_posting_cunt);
+            $ViolationProductModel=$ViolationProductModel->whereIn('online_posting_cunt', $online_posting_cunt);
+        }
+        //多选规格查询
+        if($product_specs && is_string($product_specs)){
+            $product_specs = explode(',', $product_specs);
+            $ViolationProductModel=$ViolationProductModel->whereIn('product_specs', $product_specs);
+        }
+        //多选商品查询
+        if ($product_names && is_string($product_names)) {
+            $product_names = explode(',', $product_names);
+            $ViolationProductModel=$ViolationProductModel->whereIn('product_name', $product_names);
+        }
+        //多选公司查询
+        if ($company_name && is_string($company_name)) {
+            $company_name = explode(',', $company_name);
+            $ViolationProductModel=$ViolationProductModel->whereIn('company_name', $company_name);
+        }
+        //多选第一责任人
+        if ($first_responsible_person && is_string($first_responsible_person)) {
+            $first_responsible_person = explode(',', $first_responsible_person);
+            $subQuery = $ViolationProductMemberModel->whereIn('employee_id', $first_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationProductModel = $ViolationProductModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选责任人
+        if ($responsible_person && is_string($responsible_person)) {
+            $responsible_person = explode(',', $responsible_person);
+            $subQuery = $ViolationProductMemberModel->whereIn('employee_id', $responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationProductModel = $ViolationProductModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选溯源责任人
+        if ($source_responsible_person && is_string($source_responsible_person)) {
+            $source_responsible_person = explode(',', $source_responsible_person);
+            $subQuery = $ViolationProductMemberModel->whereIn('employee_id', $source_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationProductModel = $ViolationProductModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
         $result = $ViolationProductModel->query()
             ->where($map)
             ->orderByDesc('id')
             ->paginate($limit)->toarray();
         // 分配数据
-        if (!$result)  return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
+        if (!$result)  json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
         if (isset($result['data']) && count($result['data']) > 0) {
             foreach ($result['data'] as $key => $value) {
                 //查询第一责任人名称
@@ -88,6 +146,216 @@ class ViolationProduct extends Controller
         return        json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $result]);
     }
 
+    /**
+     * 列表导出
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_excel(Request $request, ViolationProductModel $ViolationProductModel, EmployeeModel $EmployeeModel)
+    {
+        $request->scene('export_excel')->validate();
+        // 查询条件
+        $map  = [];
+        $limit = request('limit', config('page_num', 10));
+        $status    = request('status', '');
+        $start_time = request('start_time', '');
+        $end_time = request('end_time', '');
+        $product_name = request('product_name', '');
+        $first_responsible_person = request('first_responsible_person', '');
+        $responsible_person = request('responsible_person', '');
+        $platform = request('platform', '');
+        $company_name = request('company_name', '');
+        $store_name = request('store_name', '');
+        $source_responsible_person = request('source_responsible_person', '');
+        $processing_status = request('processing_status', '');
+        $product_name = request('product_name', '');
+        $product_specs = request('product_specs', '');
+        $online_posting_cunt = request('online_posting_cunt', '');
+        // 时间条件
+        if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
+        if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
+        // 其他条件
+        if ($status) $map[] = ['status', '=', $status];
+        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+
+        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
+        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
+        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
+        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
+        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
+        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
+        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
+        if ($product_name) $map[] = ['product_name', 'like', "%$product_name%"];
+        if ($product_specs) $map[] = ['product_specs', 'like', "%$product_specs%"];
+        if ($online_posting_cunt) $map[] = ['online_posting_cunt', '=', $online_posting_cunt];
+        // 查询数据
+        $result = $ViolationProductModel->query()
+            ->where($map)
+            ->orderByDesc('id')
+            ->get()->toarray();
+        // 分配数据
+        if (!$result)  return json_send(['code' => 'error', 'msg' => '暂无数据']);
+        // 处理责任人展示信息
+        $list_data = $this->processing_responsible_person($result);
+        // 导出数据
+        $this->export_download($list_data);
+    }
+
+
+    /**
+     * 处理责任人展示信息
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-12-17
+     */
+    public function processing_responsible_person($result)
+    {
+        $EmployeeModel = new EmployeeModel();
+        //获取所有员工
+        $employeee_data = $EmployeeModel->select(['id', 'name'])->get()->toarray();
+        $employeee_list = [];
+        if (!empty($employeee_data)) {
+            foreach ($employeee_data as $key => $value) {
+                $employeee_list[$value['id']] = $value['name'];
+            }
+        }
+        if (isset($result) && count($result) > 0) {
+            foreach ($result as $key => $value) {
+                //查询第一责任人名称
+                $first_responsible_person = $value['first_responsible_person'] != '' ? explode(',', $value['first_responsible_person']) : [];
+                $first_responsible_person_name = [];
+                if (!empty($first_responsible_person)) {
+                    foreach ($first_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $first_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['first_responsible_person_name'] = $first_responsible_person_name;
+                //查询责任人名称
+                $responsible_person = $value['responsible_person'] != '' ? explode(',', $value['responsible_person']) : [];
+                $responsible_person_name = [];
+                if (!empty($responsible_person)) {
+                    foreach ($responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['responsible_person_name'] = $responsible_person_name;
+                //查询来源责任人名称
+                $source_responsible_person = $value['source_responsible_person'] != '' ? explode(',', $value['source_responsible_person']) : [];
+                $source_responsible_person_name = [];
+                if (!empty($source_responsible_person)) {
+                    foreach ($source_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $source_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['source_responsible_person_name'] = $source_responsible_person_name;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * 导出下载
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_download($data)
+    {
+        // 创建一个新的 Spreadsheet 对象
+        $spreadsheet = new Spreadsheet();
+        $sheet = $spreadsheet->getActiveSheet();
+
+        //合并单元格
+        $sheet->mergeCells('A1:P1');
+        $sheet->setCellValue('A1', '违规挂网商品导出(导出时间:' . date('Y-m-d H:i:s', time()) . ')'); // 设置合并后的单元格内容
+        // 获取合并后的单元格样式对象
+        $style = $sheet->getStyle('A1');
+        // 设置水平居中和垂直居中
+        $style->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setVertical(Alignment::VERTICAL_CENTER);
+        // 然后设置行高以适应两行文本
+        $sheet->getRowDimension(1)->setRowHeight(40); // 设置行高,单位是磅(point)
+        // 设置表头
+        $sheet->setCellValue('A2', '第一责任人');
+        $sheet->setCellValue('B2', '责任人');
+        $sheet->setCellValue('C2', '平台');
+        $sheet->setCellValue('D2', '商品名称');
+        $sheet->setCellValue('E2', '商品规格');
+        $sheet->setCellValue('F2', '挂网次数');
+        $sheet->setCellValue('G2', '链接地址');
+        $sheet->setCellValue('H2', '店铺名称');
+        $sheet->setCellValue('I2', '公司名称');
+        $sheet->setCellValue('J2', '信用代码');
+        $sheet->setCellValue('K2', '省份');
+        $sheet->setCellValue('L2', '城市');
+        $sheet->setCellValue('M2', '溯源责任人');
+        $sheet->setCellValue('N2', '处理状态');
+        $sheet->setCellValue('O2', '任务状态');
+        $sheet->setCellValue('P2', '记录时间');
+
+        $platform_data = [
+            '0' => '全部',
+            '1' => '淘宝',
+            '2' => '京东',
+            '3' => '拼多多',
+            '4' => '美团',
+            '5' => '药师帮',
+            '6' => '1药城',
+            '7' => '药久久',
+        ];
+        $processing_status_text = [
+            '1' => '待处理',
+        ];
+        $status_text = [
+            '0' => '有效',
+            '1' => '无效',
+        ];
+        // 填充数据
+        $row = 3; // 从第2行开始
+        foreach ($data as $item) {
+            $first_responsible_person_name = !empty($item['first_responsible_person_name']) ? implode(',', $item['first_responsible_person_name']) : '';
+            $responsible_person_name = !empty($item['responsible_person_name']) ? implode(',', $item['responsible_person_name']) : '';
+            $source_responsible_person_name = !empty($item['source_responsible_person_name']) ? implode(',', $item['source_responsible_person_name']) : '';
+            $sheet->setCellValue('A' . $row, $first_responsible_person_name);
+            $sheet->setCellValue('B' . $row, $responsible_person_name);
+            $sheet->setCellValue('C' . $row, isset($platform_data[$item['platform']]) ? $platform_data[$item['platform']] : '');
+            $sheet->setCellValue('D' . $row, $item['product_name']);
+            $sheet->setCellValue('E' . $row, $item['product_specs']);
+            $sheet->setCellValue('F' . $row, $item['online_posting_cunt']);
+            $sheet->setCellValue('G' . $row, $item['link_url']);
+            $sheet->setCellValue('H' . $row, $item['store_name']);
+            $sheet->setCellValue('I' . $row, $item['company_name']);
+            $sheet->setCellValue('J' . $row, $item['social_credit_code']);
+            $sheet->setCellValue('K' . $row, $item['province_name']);
+            $sheet->setCellValue('L' . $row, $item['city_name']);
+            $sheet->setCellValue('M' . $row, $source_responsible_person_name);
+            $sheet->setCellValue('N' . $row, isset($processing_status_text[$item['processing_status']]) ? $processing_status_text[$item['processing_status']] : '');
+            $sheet->setCellValue('O' . $row, isset($status_text[$item['status']]) ? $status_text[$item['status']] : '');
+            $sheet->setCellValue('P' . $row, date('Y-m-d H:i:s', $item['insert_time']));
+            $row++;
+        }
+        foreach (range('A', 'P') as $column) {
+            $sheet->getColumnDimension($column)->setAutoSize(true);
+        }
+        // 生成 Excel 文件
+        $writer = new Xlsx($spreadsheet);
+
+        // 直接输出到浏览器(下载)
+        $filename = '违规挂网商品数据' . date('YmdHis') . '.xlsx';
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+        header('Content-Disposition: attachment;filename="' . $filename . '"');
+        header('Cache-Control: max-age=0');
+        $writer->save('php://output');
+        exit;
+    }
+
+
     /**
      * 详情
      * @author    唐远望
@@ -105,15 +373,15 @@ class ViolationProduct extends Controller
         //查询第一责任人名称
         $first_responsible_person = explode(',', $data->first_responsible_person);
         $first_responsible_person_name = $EmployeeModel->whereIn('id', $first_responsible_person)->pluck('name')->toarray();
-        $data->first_responsible_person_name= $first_responsible_person_name;
+        $data->first_responsible_person_name = $first_responsible_person_name;
         //查询责任人名称
         $responsible_person = explode(',', $data->responsible_person);
         $responsible_person_name = $EmployeeModel->whereIn('id', $responsible_person)->pluck('name')->toarray();
-        $data->responsible_person_name= $responsible_person_name;
+        $data->responsible_person_name = $responsible_person_name;
         //查询来源责任人名称
         $source_responsible_person = explode(',', $data->source_responsible_person);
         $source_responsible_person_name = $EmployeeModel->whereIn('id', $source_responsible_person)->pluck('name')->toarray();
-        $data->source_responsible_person_name= $source_responsible_person_name;
+        $data->source_responsible_person_name = $source_responsible_person_name;
         // 加载模板
         return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $data]);
     }

+ 272 - 11
app/Http/Controllers/Manager/Process/ViolationStore.php

@@ -7,6 +7,10 @@ use App\Http\Requests\Manager\Process\ViolationStore as Request;
 use App\Models\Manager\Process\ViolationStore as ViolationStoreModel;
 use App\Jobs\Manager\Process\ViolationStoreJobs;
 use App\Models\Manager\Personnel\Employee as EmployeeModel;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use PhpOffice\PhpSpreadsheet\Style\Alignment;
+use App\Models\Api\Process\ViolationStoreMember as ViolationStoreMemberModel;
 
 /**
  * 违规处理-违规店铺
@@ -23,10 +27,11 @@ class ViolationStore extends Controller
      * @date      2025-12-08
      * 
      */
-    public function list(Request $request, ViolationStoreModel $ViolationStoreModel, EmployeeModel $EmployeeModel)
+    public function list(Request $request, ViolationStoreModel $ViolationStoreModel,EmployeeModel $EmployeeModel,ViolationStoreMemberModel $ViolationStoreMemberModel)
     {
         $request->scene('list')->validate();
         // 查询条件
+       // 查询条件
         $map  = [];
         $limit = request('limit', config('page_num', 10));
         $status    = request('status', '');
@@ -37,28 +42,83 @@ class ViolationStore extends Controller
         $platform = request('platform', '');
         $company_name = request('company_name', '');
         $store_name = request('store_name', '');
+        $store_names = request('store_names', '');
         $source_responsible_person = request('source_responsible_person', '');
         $processing_status = request('processing_status', '');
+        $product_specs = request('product_specs', '');
+        $online_posting_cunt = request('online_posting_cunt', '');
         // 时间条件
         if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
         if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
-        // 其他条件
-        if (is_numeric($status)) $map[] = ['status', '=', $status];
+        //其它条件
+        if ($store_name) $map[]   = ['store_name','like',"%$store_name%"];
 
-        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
-        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
-        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
-        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
-        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
-        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
-        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
+        //多选平台查询
+        if($platform && is_string($platform)){
+            $platform = explode(',', $platform);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('platform', $platform);
+        }
+        //多选处理状态查询
+        if($processing_status && is_string($processing_status)){
+            $processing_status = explode(',', $processing_status);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('processing_status', $processing_status);
+        }
+        //多选状态查询
+        if($status && is_string($status)){
+            $status = explode(',', $status);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('status', $status);
+        }
+        //多选店铺名称查询
+        if($store_names && is_string($store_names)){
+            $store_names = explode(',', $store_names);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('store_name', $store_names);
+        }
+        //多选违规挂网次数查询
+        if($online_posting_cunt && is_string($online_posting_cunt)){
+            $online_posting_cunt = explode(',', $online_posting_cunt);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('online_posting_cunt', $online_posting_cunt);
+        }
+        //多选规格查询
+        if($product_specs && is_string($product_specs)){
+            $product_specs = explode(',', $product_specs);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('product_specs', $product_specs);
+        }
+        //多选公司查询
+        if ($company_name && is_string($company_name)) {
+            $company_name = explode(',', $company_name);
+            $ViolationStoreModel=$ViolationStoreModel->whereIn('company_name', $company_name);
+        }
+        //多选第一责任人
+        if ($first_responsible_person && is_string($first_responsible_person)) {
+            $first_responsible_person = explode(',', $first_responsible_person);
+            $subQuery = $ViolationStoreMemberModel->whereIn('employee_id', $first_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationStoreModel = $ViolationStoreModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选责任人
+        if ($responsible_person && is_string($responsible_person)) {
+            $responsible_person = explode(',', $responsible_person);
+            $subQuery = $ViolationStoreMemberModel->whereIn('employee_id', $responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationStoreModel = $ViolationStoreModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
+        //多选溯源责任人
+        if ($source_responsible_person && is_string($source_responsible_person)) {
+            $source_responsible_person = explode(',', $source_responsible_person);
+            $subQuery = $ViolationStoreMemberModel->whereIn('employee_id', $source_responsible_person)->distinct('lowprice_product_logid')->select('lowprice_product_logid');
+            $ViolationStoreModel = $ViolationStoreModel->whereIn('id', function ($query1) use ($subQuery) {
+                $query1->select('lowprice_product_logid')->fromSub($subQuery, 'sub1');
+            });
+        }
         // 查询数据
         $result = $ViolationStoreModel->query()
             ->where($map)
             ->orderByDesc('id')
             ->paginate($limit)->toarray();
         // 分配数据
-        if (!$result)  return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
+        if (!$result)  json_send(['code' => 'success', 'msg' => '获取成功', 'data' => []]);
         if (isset($result['data']) && count($result['data']) > 0) {
             foreach ($result['data'] as $key => $value) {
                 //查询第一责任人名称
@@ -79,6 +139,207 @@ class ViolationStore extends Controller
         return        json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $result]);
     }
 
+    /**
+     * 列表导出
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_excel(Request $request, ViolationStoreModel $ViolationStoreModel, EmployeeModel $EmployeeModel)
+    {
+        $request->scene('export_excel')->validate();
+        // 查询条件
+        $map  = [];
+        $limit = request('limit', config('page_num', 10));
+        $status    = request('status', '');
+        $start_time = request('start_time', '');
+        $end_time = request('end_time', '');
+        $first_responsible_person = request('first_responsible_person', '');
+        $responsible_person = request('responsible_person', '');
+        $platform = request('platform', '');
+        $company_name = request('company_name', '');
+        $store_name = request('store_name', '');
+        $source_responsible_person = request('source_responsible_person', '');
+        $processing_status = request('processing_status', '');
+        // 时间条件
+        if ($start_time) $map[] = ['insert_time', '>=', strtotime($start_time)];
+        if ($end_time) $map[]   = ['insert_time', '<=', strtotime($end_time)];
+        // 其他条件
+        if (is_numeric($status)) $map[] = ['status', '=', $status];
+
+        if ($first_responsible_person) $map[] = ['first_responsible_person', 'like', "%,$first_responsible_person,%"];
+        if ($responsible_person) $map[] = ['responsible_person', 'like', "%,$responsible_person,%"];
+        if ($platform) $map[] = ['platform', 'like', "%$platform%"];
+        if ($company_name) $map[] = ['company_name', 'like', "%$company_name%"];
+        if ($store_name) $map[] = ['store_name', 'like', "%$store_name%"];
+        if ($source_responsible_person) $map[] = ['source_responsible_person', 'like', "%,$source_responsible_person,%"];
+        if ($processing_status) $map[] = ['processing_status', '=', $processing_status];
+        // 查询数据
+        $result = $ViolationStoreModel->query()
+            ->where($map)
+            ->orderByDesc('id')
+            ->get()->toarray();
+        // 分配数据
+        if (!$result)  return json_send(['code' => 'error', 'msg' => '暂无数据']);
+        // 处理责任人展示信息
+        $list_data = $this->processing_responsible_person($result);
+        // 导出数据
+        $this->export_download($list_data);
+    }
+
+
+    /**
+     * 处理责任人展示信息
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-12-17
+     */
+    public function processing_responsible_person($result)
+    {
+        $EmployeeModel = new EmployeeModel();
+        //获取所有员工
+        $employeee_data = $EmployeeModel->select(['id', 'name'])->get()->toarray();
+        $employeee_list = [];
+        if (!empty($employeee_data)) {
+            foreach ($employeee_data as $key => $value) {
+                $employeee_list[$value['id']] = $value['name'];
+            }
+        }
+        if (isset($result) && count($result) > 0) {
+            foreach ($result as $key => $value) {
+                //查询第一责任人名称
+                $first_responsible_person = $value['first_responsible_person'] != '' ? explode(',', $value['first_responsible_person']) : [];
+                $first_responsible_person_name = [];
+                if (!empty($first_responsible_person)) {
+                    foreach ($first_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $first_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['first_responsible_person_name'] = $first_responsible_person_name;
+                //查询责任人名称
+                $responsible_person = $value['responsible_person'] != '' ? explode(',', $value['responsible_person']) : [];
+                $responsible_person_name = [];
+                if (!empty($responsible_person)) {
+                    foreach ($responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['responsible_person_name'] = $responsible_person_name;
+                //查询来源责任人名称
+                $source_responsible_person = $value['source_responsible_person'] != '' ? explode(',', $value['source_responsible_person']) : [];
+                $source_responsible_person_name = [];
+                if (!empty($source_responsible_person)) {
+                    foreach ($source_responsible_person as $k => $v) {
+                        if (isset($employeee_list[$v])) {
+                            $source_responsible_person_name[] = $employeee_list[$v];
+                        }
+                    }
+                }
+                $result[$key]['source_responsible_person_name'] = $source_responsible_person_name;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * 导出下载
+     * @author 唐远望
+     * @version 1.0
+     * @date 2025-06-17
+     */
+    public function export_download($data)
+    {
+        // 创建一个新的 Spreadsheet 对象
+        $spreadsheet = new Spreadsheet();
+        $sheet = $spreadsheet->getActiveSheet();
+
+        //合并单元格
+        $sheet->mergeCells('A1:P1');
+        $sheet->setCellValue('A1', '违规挂网商品导出(导出时间:' . date('Y-m-d H:i:s', time()) . ')'); // 设置合并后的单元格内容
+        // 获取合并后的单元格样式对象
+        $style = $sheet->getStyle('A1');
+        // 设置水平居中和垂直居中
+        $style->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER)->setVertical(Alignment::VERTICAL_CENTER);
+        // 然后设置行高以适应两行文本
+        $sheet->getRowDimension(1)->setRowHeight(40); // 设置行高,单位是磅(point)
+        // 设置表头
+        $sheet->setCellValue('A2', '第一责任人');
+        $sheet->setCellValue('B2', '责任人');
+        $sheet->setCellValue('C2', '平台');
+        $sheet->setCellValue('D2', '商品名称');
+        $sheet->setCellValue('E2', '商品规格');
+        $sheet->setCellValue('F2', '挂网次数');
+        $sheet->setCellValue('G2', '链接地址');
+        $sheet->setCellValue('H2', '店铺名称');
+        $sheet->setCellValue('I2', '公司名称');
+        $sheet->setCellValue('J2', '信用代码');
+        $sheet->setCellValue('K2', '省份');
+        $sheet->setCellValue('L2', '城市');
+        $sheet->setCellValue('M2', '溯源责任人');
+        $sheet->setCellValue('N2', '处理状态');
+        $sheet->setCellValue('O2', '任务状态');
+        $sheet->setCellValue('P2', '记录时间');
+
+        $platform_data = [
+            '0' => '全部',
+            '1' => '淘宝',
+            '2' => '京东',
+            '3' => '拼多多',
+            '4' => '美团',
+            '5' => '药师帮',
+            '6' => '1药城',
+            '7' => '药久久',
+        ];
+        $processing_status_text = [
+            '1' => '待处理',
+        ];
+        $status_text = [
+            '0' => '有效',
+            '1' => '无效',
+        ];
+        // 填充数据
+        $row = 3; // 从第2行开始
+        foreach ($data as $item) {
+            $first_responsible_person_name = !empty($item['first_responsible_person_name']) ? implode(',', $item['first_responsible_person_name']) : '';
+            $responsible_person_name = !empty($item['responsible_person_name']) ? implode(',', $item['responsible_person_name']) : '';
+            $source_responsible_person_name = !empty($item['source_responsible_person_name']) ? implode(',', $item['source_responsible_person_name']) : '';
+            $sheet->setCellValue('A' . $row, $first_responsible_person_name);
+            $sheet->setCellValue('B' . $row, $responsible_person_name);
+            $sheet->setCellValue('C' . $row, isset($platform_data[$item['platform']]) ? $platform_data[$item['platform']] : '');
+            $sheet->setCellValue('D' . $row, $item['product_name']);
+            $sheet->setCellValue('E' . $row, $item['product_specs']);
+            $sheet->setCellValue('F' . $row, $item['online_posting_cunt']);
+            $sheet->setCellValue('G' . $row, $item['link_url']);
+            $sheet->setCellValue('H' . $row, $item['store_name']);
+            $sheet->setCellValue('I' . $row, $item['company_name']);
+            $sheet->setCellValue('J' . $row, $item['social_credit_code']);
+            $sheet->setCellValue('K' . $row, $item['province_name']);
+            $sheet->setCellValue('L' . $row, $item['city_name']);
+            $sheet->setCellValue('M' . $row, $source_responsible_person_name);
+            $sheet->setCellValue('N' . $row, isset($processing_status_text[$item['processing_status']]) ? $processing_status_text[$item['processing_status']] : '');
+            $sheet->setCellValue('O' . $row, isset($status_text[$item['status']]) ? $status_text[$item['status']] : '');
+            $sheet->setCellValue('P' . $row, date('Y-m-d H:i:s', $item['insert_time']));
+            $row++;
+        }
+        foreach (range('A', 'P') as $column) {
+            $sheet->getColumnDimension($column)->setAutoSize(true);
+        }
+        // 生成 Excel 文件
+        $writer = new Xlsx($spreadsheet);
+
+        // 直接输出到浏览器(下载)
+        $filename = '违规挂网商品数据' . date('YmdHis') . '.xlsx';
+        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+        header('Content-Disposition: attachment;filename="' . $filename . '"');
+        header('Cache-Control: max-age=0');
+        $writer->save('php://output');
+        exit;
+    }
+
     /**
      * 详情
      * @author    唐远望

+ 1 - 0
composer.json

@@ -16,6 +16,7 @@
         "laravel/framework": "^8.75",
         "laravel/sanctum": "^2.11",
         "laravel/tinker": "^2.5",
+        "phpoffice/phpspreadsheet": "^1.12",
         "vinkla/hashids": "^9.1",
         "wantp/snowflake": "^1.2"
     },

+ 288 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "1e681333ab55bfbee2c509519c49e4b6",
+    "content-hash": "7546cf1ca341ac4a15fd76a2bcbcfd43",
     "packages": [
         {
             "name": "asm89/stack-cors",
@@ -2174,6 +2174,190 @@
             ],
             "time": "2024-01-28T23:22:08+00:00"
         },
+        {
+            "name": "markbaker/complex",
+            "version": "1.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPComplex.git",
+                "reference": "c3131244e29c08d44fefb49e0dd35021e9e39dd2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/c3131244e29c08d44fefb49e0dd35021e9e39dd2",
+                "reference": "c3131244e29c08d44fefb49e0dd35021e9e39dd2",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^5.6.0|^7.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
+                "phpcompatibility/php-compatibility": "^9.0",
+                "phpdocumentor/phpdocumentor": "2.*",
+                "phploc/phploc": "^4.0|^5.0|^6.0|^7.0",
+                "phpmd/phpmd": "2.*",
+                "phpunit/phpunit": "^4.8.35|^5.0|^6.0|^7.0",
+                "sebastian/phpcpd": "2.*",
+                "squizlabs/php_codesniffer": "^3.4.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "classes/src/functions/abs.php",
+                    "classes/src/functions/acos.php",
+                    "classes/src/functions/acosh.php",
+                    "classes/src/functions/acot.php",
+                    "classes/src/functions/acoth.php",
+                    "classes/src/functions/acsc.php",
+                    "classes/src/functions/acsch.php",
+                    "classes/src/functions/argument.php",
+                    "classes/src/functions/asec.php",
+                    "classes/src/functions/asech.php",
+                    "classes/src/functions/asin.php",
+                    "classes/src/functions/asinh.php",
+                    "classes/src/functions/atan.php",
+                    "classes/src/functions/atanh.php",
+                    "classes/src/functions/conjugate.php",
+                    "classes/src/functions/cos.php",
+                    "classes/src/functions/cosh.php",
+                    "classes/src/functions/cot.php",
+                    "classes/src/functions/coth.php",
+                    "classes/src/functions/csc.php",
+                    "classes/src/functions/csch.php",
+                    "classes/src/functions/exp.php",
+                    "classes/src/functions/inverse.php",
+                    "classes/src/functions/ln.php",
+                    "classes/src/functions/log2.php",
+                    "classes/src/functions/log10.php",
+                    "classes/src/functions/negative.php",
+                    "classes/src/functions/pow.php",
+                    "classes/src/functions/rho.php",
+                    "classes/src/functions/sec.php",
+                    "classes/src/functions/sech.php",
+                    "classes/src/functions/sin.php",
+                    "classes/src/functions/sinh.php",
+                    "classes/src/functions/sqrt.php",
+                    "classes/src/functions/tan.php",
+                    "classes/src/functions/tanh.php",
+                    "classes/src/functions/theta.php",
+                    "classes/src/operations/add.php",
+                    "classes/src/operations/subtract.php",
+                    "classes/src/operations/multiply.php",
+                    "classes/src/operations/divideby.php",
+                    "classes/src/operations/divideinto.php"
+                ],
+                "psr-4": {
+                    "Complex\\": "classes/src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mark Baker",
+                    "email": "mark@lange.demon.co.uk"
+                }
+            ],
+            "description": "PHP Class for working with complex numbers",
+            "homepage": "https://github.com/MarkBaker/PHPComplex",
+            "keywords": [
+                "complex",
+                "mathematics"
+            ],
+            "support": {
+                "issues": "https://github.com/MarkBaker/PHPComplex/issues",
+                "source": "https://github.com/MarkBaker/PHPComplex/tree/1.5.0"
+            },
+            "time": "2020-08-26T19:47:57+00:00"
+        },
+        {
+            "name": "markbaker/matrix",
+            "version": "1.2.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPMatrix.git",
+                "reference": "44bb1ab01811116f01fe216ab37d921dccc6c10d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/44bb1ab01811116f01fe216ab37d921dccc6c10d",
+                "reference": "44bb1ab01811116f01fe216ab37d921dccc6c10d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^5.6.0|^7.0.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+                "phpcompatibility/php-compatibility": "dev-master",
+                "phploc/phploc": "^4",
+                "phpmd/phpmd": "dev-master",
+                "phpunit/phpunit": "^5.7|^6.0|7.0",
+                "sebastian/phpcpd": "^3.0",
+                "squizlabs/php_codesniffer": "^3.0@dev"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "classes/src/Functions/adjoint.php",
+                    "classes/src/Functions/antidiagonal.php",
+                    "classes/src/Functions/cofactors.php",
+                    "classes/src/Functions/determinant.php",
+                    "classes/src/Functions/diagonal.php",
+                    "classes/src/Functions/identity.php",
+                    "classes/src/Functions/inverse.php",
+                    "classes/src/Functions/minors.php",
+                    "classes/src/Functions/trace.php",
+                    "classes/src/Functions/transpose.php",
+                    "classes/src/Operations/add.php",
+                    "classes/src/Operations/directsum.php",
+                    "classes/src/Operations/subtract.php",
+                    "classes/src/Operations/multiply.php",
+                    "classes/src/Operations/divideby.php",
+                    "classes/src/Operations/divideinto.php"
+                ],
+                "psr-4": {
+                    "Matrix\\": "classes/src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mark Baker",
+                    "email": "mark@lange.demon.co.uk"
+                }
+            ],
+            "description": "PHP Class for working with matrices",
+            "homepage": "https://github.com/MarkBaker/PHPMatrix",
+            "keywords": [
+                "mathematics",
+                "matrix",
+                "vector"
+            ],
+            "support": {
+                "issues": "https://github.com/MarkBaker/PHPMatrix/issues",
+                "source": "https://github.com/MarkBaker/PHPMatrix/tree/1.2.3"
+            },
+            "time": "2021-01-26T14:36:01+00:00"
+        },
         {
             "name": "monolog/monolog",
             "version": "2.10.0",
@@ -2690,6 +2874,109 @@
             },
             "time": "2022-01-27T09:35:39+00:00"
         },
+        {
+            "name": "phpoffice/phpspreadsheet",
+            "version": "1.12.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+                "reference": "f79611d6dc1f6b7e8e30b738fc371b392001dbfd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/f79611d6dc1f6b7e8e30b738fc371b392001dbfd",
+                "reference": "f79611d6dc1f6b7e8e30b738fc371b392001dbfd",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-dom": "*",
+                "ext-fileinfo": "*",
+                "ext-gd": "*",
+                "ext-iconv": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "ext-xml": "*",
+                "ext-xmlreader": "*",
+                "ext-xmlwriter": "*",
+                "ext-zip": "*",
+                "ext-zlib": "*",
+                "markbaker/complex": "^1.4",
+                "markbaker/matrix": "^1.2",
+                "php": "^7.1",
+                "psr/simple-cache": "^1.0"
+            },
+            "require-dev": {
+                "dompdf/dompdf": "^0.8.3",
+                "friendsofphp/php-cs-fixer": "^2.16",
+                "jpgraph/jpgraph": "^4.0",
+                "mpdf/mpdf": "^8.0",
+                "phpcompatibility/php-compatibility": "^9.3",
+                "phpunit/phpunit": "^7.5",
+                "squizlabs/php_codesniffer": "^3.5",
+                "tecnickcom/tcpdf": "^6.3"
+            },
+            "suggest": {
+                "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
+                "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+                "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+                "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Maarten Balliauw",
+                    "homepage": "https://blog.maartenballiauw.be"
+                },
+                {
+                    "name": "Mark Baker",
+                    "homepage": "https://markbakeruk.net"
+                },
+                {
+                    "name": "Franck Lefevre",
+                    "homepage": "https://rootslabs.net"
+                },
+                {
+                    "name": "Erik Tilt"
+                },
+                {
+                    "name": "Adrien Crivelli"
+                }
+            ],
+            "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+            "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+            "keywords": [
+                "OpenXML",
+                "excel",
+                "gnumeric",
+                "ods",
+                "php",
+                "spreadsheet",
+                "xls",
+                "xlsx"
+            ],
+            "support": {
+                "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
+                "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.12.0"
+            },
+            "time": "2020-04-27T08:12:48+00:00"
+        },
         {
             "name": "phpoption/phpoption",
             "version": "1.9.3",

+ 7 - 1
routes/manager.php

@@ -162,6 +162,8 @@ Route::any('process/low_price_goods/set_processing_status', [App\Http\Controller
 Route::any('process/low_price_goods/delete', [App\Http\Controllers\Manager\Process\LowPriceGoods::class, 'delete']);
 // 低价挂网商品违规处理-执行数据清洗
 Route::any('process/low_price_goods/data_cleaning', [App\Http\Controllers\Manager\Process\LowPriceGoods::class, 'data_cleaning']);
+// 低价挂网商品违规处理-导出Excel
+Route::any('process/low_price_goods/export_excel', [App\Http\Controllers\Manager\Process\LowPriceGoods::class, 'export_excel']);
 
 // 违规挂网商品违规处理-列表
 Route::any('process/violation_goods/list', [App\Http\Controllers\Manager\Process\ViolationProduct::class, 'list']);
@@ -177,6 +179,8 @@ Route::any('process/violation_goods/set_processing_status', [App\Http\Controller
 Route::any('process/violation_goods/delete', [App\Http\Controllers\Manager\Process\ViolationProduct::class, 'delete']);
 // 违规挂网商品违规处理-执行数据清洗
 Route::any('process/violation_goods/data_cleaning', [App\Http\Controllers\Manager\Process\ViolationProduct::class, 'data_cleaning']);
+// 违规挂网商品违规处理-导出Excel
+Route::any('process/violation_goods/export_excel', [App\Http\Controllers\Manager\Process\ViolationProduct::class, 'export_excel']);
 
 // 违规店铺违规处理-列表
 Route::any('process/violation_store/list', [App\Http\Controllers\Manager\Process\ViolationStore::class, 'list']);
@@ -191,4 +195,6 @@ Route::any('process/violation_store/set_processing_status', [App\Http\Controller
 // 违规店铺违规处理-删除
 Route::any('process/violation_store/delete', [App\Http\Controllers\Manager\Process\ViolationStore::class, 'delete']);
 // 违规店铺违规处理-执行数据清洗
-Route::any('process/violation_store/data_cleaning', [App\Http\Controllers\Manager\Process\ViolationStore::class, 'data_cleaning']);
+Route::any('process/violation_store/data_cleaning', [App\Http\Controllers\Manager\Process\ViolationStore::class, 'data_cleaning']);
+// 违规店铺违规处理-导出Excel
+Route::any('process/violation_store/export_excel', [App\Http\Controllers\Manager\Process\ViolationStore::class, 'export_excel']);