作者 Your Name

Merge branch 'dev' of http://47.244.231.31:8099/zhl/globalso-v6 into dev

@@ -17,3 +17,4 @@ yarn-error.log @@ -17,3 +17,4 @@ yarn-error.log
17 composer.lock 17 composer.lock
18 app/Console/Commands/Test/Demo.php 18 app/Console/Commands/Test/Demo.php
19 /public/upload 19 /public/upload
  20 +/public/runtime
@@ -2,11 +2,16 @@ @@ -2,11 +2,16 @@
2 2
3 namespace App\Http\Controllers\Bside; 3 namespace App\Http\Controllers\Bside;
4 4
  5 +use App\Exceptions\BsideGlobalException;
5 use App\Helper\Arr; 6 use App\Helper\Arr;
6 use App\Http\Logic\Bside\InquiryLogic; 7 use App\Http\Logic\Bside\InquiryLogic;
7 use App\Http\Requests\Bside\InquiryRequest; 8 use App\Http\Requests\Bside\InquiryRequest;
8 use App\Rules\Ids; 9 use App\Rules\Ids;
  10 +use App\Services\BatchExportService;
9 use Illuminate\Http\Request; 11 use Illuminate\Http\Request;
  12 +use Illuminate\Support\Facades\Storage;
  13 +use Illuminate\Validation\ValidationException;
  14 +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
10 15
11 /** 16 /**
12 * 精准询盘 17 * 精准询盘
@@ -51,4 +56,42 @@ class InquiryController extends BaseController @@ -51,4 +56,42 @@ class InquiryController extends BaseController
51 return $this->success($data); 56 return $this->success($data);
52 } 57 }
53 58
  59 + /**
  60 + * 导出
  61 + * @param InquiryLogic $logic
  62 + * @return \Illuminate\Http\JsonResponse
  63 + * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
  64 + * @author zbj
  65 + * @date 2023/5/8
  66 + */
  67 + public function export(InquiryLogic $logic)
  68 + {
  69 + $sort = ['id' => 'desc'];
  70 + //最多到1w条
  71 + $data = $logic->getList([], $sort, ['name', 'email', 'phone', 'url', 'ip', 'ip_country', 'content', 'created_at'], 10000);
  72 + $data = $data['list'] ?? [];
  73 + foreach ($data as &$item){
  74 + $item['ip_address'] = "{$item['ip_country']}({$item['ip']})";
  75 + }
  76 +
  77 + $map = [
  78 + 'created_at' => '询盘发送时间',
  79 + 'name' => '姓名',
  80 + 'email' => '邮箱',
  81 + 'phone' => '电话',
  82 + 'ip_address' => '访问国家/地区(IP)',
  83 + 'url' => '发送页面',
  84 + 'content' => '询盘内容',
  85 + ];
  86 +
  87 + //生成文件,发送到客户端
  88 + $table = new BatchExportService("询盘数据导出");
  89 + $file = $table->head($map)->data($data)->save();
  90 + if (!$file) {
  91 + throw new \Exception('文件生成失败,请重试');
  92 + }
  93 + $fileurl = Storage::disk('runtime')->url($file);
  94 +// return Storage::disk('runtime')->download($file); //直接下载
  95 + return $this->success(['url' => $fileurl]);
  96 + }
54 } 97 }
@@ -25,11 +25,6 @@ class RouteController extends BaseController @@ -25,11 +25,6 @@ class RouteController extends BaseController
25 $source_id = $request->input('source_id'); 25 $source_id = $request->input('source_id');
26 $project_id = $this->user['project_id']; 26 $project_id = $this->user['project_id'];
27 27
28 - //有中文先翻译  
29 - if(preg_match('/[\x{4e00}-\x{9fa5}]/u', $title)){  
30 - $title = Translate::tran($title, 'en');  
31 - }  
32 -  
33 $route = RouteMap::generateRoute($title, $source, $source_id, $project_id); 28 $route = RouteMap::generateRoute($title, $source, $source_id, $project_id);
34 return $this->success(['route' => $route]); 29 return $this->success(['route' => $route]);
35 } 30 }
@@ -66,7 +66,7 @@ class ProjectGroupController extends BaseController @@ -66,7 +66,7 @@ class ProjectGroupController extends BaseController
66 */ 66 */
67 public function add(ProjectGroupRequest $request,GroupLogic $groupLogic){ 67 public function add(ProjectGroupRequest $request,GroupLogic $groupLogic){
68 $request->validated(); 68 $request->validated();
69 - $groupLogic->group_add($this->param); 69 + $groupLogic->group_add();
70 $this->response('success'); 70 $this->response('success');
71 } 71 }
72 72
@@ -101,7 +101,7 @@ class ProjectGroupController extends BaseController @@ -101,7 +101,7 @@ class ProjectGroupController extends BaseController
101 'id.required' => 'ID不能为空', 101 'id.required' => 'ID不能为空',
102 'id.array' => 'ID为数组', 102 'id.array' => 'ID为数组',
103 ]); 103 ]);
104 - $groupLogic->group_del($this->param); 104 + $groupLogic->group_del();
105 $this->response('success'); 105 $this->response('success');
106 } 106 }
107 } 107 }
@@ -41,7 +41,7 @@ class WebSettingFromLogic extends BaseLogic @@ -41,7 +41,7 @@ class WebSettingFromLogic extends BaseLogic
41 //删除以前的数据 41 //删除以前的数据
42 $this->model->del(['project_id'=>$this->user['project_id']]); 42 $this->model->del(['project_id'=>$this->user['project_id']]);
43 //新增 43 //新增
44 - $this->model->add($this->param['data']); 44 + $this->model->add_all($this->param['data']);
45 }catch (\Exception $e){ 45 }catch (\Exception $e){
46 $this->fail('error'); 46 $this->fail('error');
47 } 47 }
@@ -22,7 +22,7 @@ class WebSettingReceivingLogic extends BaseLogic @@ -22,7 +22,7 @@ class WebSettingReceivingLogic extends BaseLogic
22 * @time :2023/5/8 16:17 22 * @time :2023/5/8 16:17
23 */ 23 */
24 public function setting_receiving_lists(){ 24 public function setting_receiving_lists(){
25 - $lists = $this->model->list(['project_id'=>$this->user['project_id']]); 25 + $lists = $this->model->list(['project_id'=>$this->user['project_id']],'created_at');
26 return $this->success($lists); 26 return $this->success($lists);
27 } 27 }
28 28
@@ -39,7 +39,7 @@ class WebSettingReceivingLogic extends BaseLogic @@ -39,7 +39,7 @@ class WebSettingReceivingLogic extends BaseLogic
39 $v['project_id'] = $this->user['project_id']; 39 $v['project_id'] = $this->user['project_id'];
40 $this->param['data'][$k] = $v; 40 $this->param['data'][$k] = $v;
41 } 41 }
42 - $this->model->add($this->param['data']); 42 + $this->model->add_all($this->param['data']);
43 }catch (\Exception $e){ 43 }catch (\Exception $e){
44 $this->fail('error'); 44 $this->fail('error');
45 } 45 }
@@ -42,7 +42,7 @@ class WebSettingServiceLogic extends BaseLogic @@ -42,7 +42,7 @@ class WebSettingServiceLogic extends BaseLogic
42 $v['project_id'] = $this->user['project_id']; 42 $v['project_id'] = $this->user['project_id'];
43 $this->param['data'][$k] = $v; 43 $this->param['data'][$k] = $v;
44 } 44 }
45 - $this->model->add($this->param['data']); 45 + $this->model->add_all($this->param['data']);
46 }catch (\Exception $e){ 46 }catch (\Exception $e){
47 $this->fail('error'); 47 $this->fail('error');
48 } 48 }
@@ -69,7 +69,7 @@ class WebSettingTextLogic extends BaseLogic @@ -69,7 +69,7 @@ class WebSettingTextLogic extends BaseLogic
69 $v['project_id'] = $this->user['project_id']; 69 $v['project_id'] = $this->user['project_id'];
70 $this->param['data'][$k] = $v; 70 $this->param['data'][$k] = $v;
71 } 71 }
72 - $this->model->add($this->param['data']); 72 + $this->model->add_all($this->param['data']);
73 DB::commit(); 73 DB::commit();
74 }catch (\Exception $e){ 74 }catch (\Exception $e){
75 DB::rollBack(); 75 DB::rollBack();
@@ -14,10 +14,6 @@ class GroupLogic extends BaseLogic @@ -14,10 +14,6 @@ class GroupLogic extends BaseLogic
14 $this->model = new ProjectGroup(); 14 $this->model = new ProjectGroup();
15 $this->param = $this->requestAll; 15 $this->param = $this->requestAll;
16 } 16 }
17 -  
18 - public function user_list(){  
19 - return $this->success();  
20 - }  
21 /** 17 /**
22 * @name :添加 18 * @name :添加
23 * @return void 19 * @return void
@@ -25,6 +21,10 @@ class GroupLogic extends BaseLogic @@ -25,6 +21,10 @@ class GroupLogic extends BaseLogic
25 * @method 21 * @method
26 */ 22 */
27 public function group_add(){ 23 public function group_add(){
  24 + $rs = $this->model->add($this->param);
  25 + if($rs === false){
  26 + $this->fail('error');
  27 + }
28 return $this->success(); 28 return $this->success();
29 } 29 }
30 30
@@ -35,6 +35,10 @@ class GroupLogic extends BaseLogic @@ -35,6 +35,10 @@ class GroupLogic extends BaseLogic
35 * @method 35 * @method
36 */ 36 */
37 public function group_edit(){ 37 public function group_edit(){
  38 + $rs = $this->edit($this->param,['id'=>$this->param['id']]);
  39 + if($rs === false){
  40 + $this->fail('error');
  41 + }
38 return $this->success(); 42 return $this->success();
39 } 43 }
40 44
@@ -45,7 +49,9 @@ class GroupLogic extends BaseLogic @@ -45,7 +49,9 @@ class GroupLogic extends BaseLogic
45 * @method 49 * @method
46 */ 50 */
47 public function group_info(){ 51 public function group_info(){
48 - return $this->success(); 52 + $info = $this->info($this->param);
  53 +
  54 + return $this->success($info);
49 } 55 }
50 56
51 /** 57 /**
@@ -55,6 +61,12 @@ class GroupLogic extends BaseLogic @@ -55,6 +61,12 @@ class GroupLogic extends BaseLogic
55 * @method 61 * @method
56 */ 62 */
57 public function group_del(){ 63 public function group_del(){
  64 + $ids = $this->param['id'];
  65 + $this->param['id'] = ['in',$this->param['id']];
  66 + $rs = $this->del($this->param,$ids);
  67 + if($rs === false){
  68 + $this->fail('error');
  69 + }
58 return $this->success(); 70 return $this->success();
59 } 71 }
60 } 72 }
@@ -134,6 +134,21 @@ class Base extends Model @@ -134,6 +134,21 @@ class Base extends Model
134 $data['updated_at'] = date('Y-m-d H:i:s'); 134 $data['updated_at'] = date('Y-m-d H:i:s');
135 return $this->insert($data); 135 return $this->insert($data);
136 } 136 }
  137 +
  138 + /**
  139 + * @name :(批量插入)add_all
  140 + * @author :lyh
  141 + * @method :post
  142 + * @time :2023/5/8 17:41
  143 + */
  144 + public function add_all($data){
  145 + foreach ($data as $k => $v){
  146 + $v['created_at'] = date('Y-m-d H:i:s');
  147 + $v['updated_at'] = date('Y-m-d H:i:s');
  148 + $data[$k] = $v;
  149 + }
  150 + return $this->insert($data);
  151 + }
137 /** 152 /**
138 * @name :编辑 153 * @name :编辑
139 * @return void 154 * @return void
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 namespace App\Models; 3 namespace App\Models;
4 4
  5 +use App\Helper\Translate;
5 use Illuminate\Database\Eloquent\Model; 6 use Illuminate\Database\Eloquent\Model;
6 use Illuminate\Support\Facades\Log; 7 use Illuminate\Support\Facades\Log;
7 8
@@ -36,6 +37,11 @@ class RouteMap extends Model @@ -36,6 +37,11 @@ class RouteMap extends Model
36 * @date 2023/4/17 37 * @date 2023/4/17
37 */ 38 */
38 public static function generateRoute($title, $source, $source_id, $project_id){ 39 public static function generateRoute($title, $source, $source_id, $project_id){
  40 + //有中文先翻译
  41 + if(preg_match('/[\x{4e00}-\x{9fa5}]/u', $title)){
  42 + $title = Translate::tran($title, 'en');
  43 + }
  44 +
39 $i=1; 45 $i=1;
40 $sign = generateRoute($title); 46 $sign = generateRoute($title);
41 $route = $sign; 47 $route = $sign;
  1 +<?php
  2 +
  3 +namespace App\Services;
  4 +
  5 +use Illuminate\Support\Facades\File;
  6 +use Illuminate\Support\Facades\Storage;
  7 +use PhpOffice\PhpSpreadsheet\Spreadsheet;
  8 +use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  9 +
  10 +/**
  11 + * 批量导出
  12 + * Class BatchExportService
  13 + * @package App\Services
  14 + * @author zbj
  15 + * @date 2023/5/8
  16 + */
  17 +class BatchExportService
  18 +{
  19 +
  20 + private $name = '';
  21 + /**
  22 + * @var array
  23 + */
  24 + private $data = [];
  25 +
  26 +
  27 + /**
  28 + * @var null | \PhpOffice\PhpSpreadsheet\Spreadsheet;
  29 + */
  30 + private $spreadsheet = null;
  31 +
  32 +
  33 + /**
  34 + * 包头与字段映射
  35 + * @var array
  36 + */
  37 + private $head = [];
  38 +
  39 +
  40 + public function __construct($name)
  41 + {
  42 + $this->name = $name;
  43 + $this->spreadsheet = new Spreadsheet();
  44 + $this->spreadsheet->setActiveSheetIndex(0);
  45 + }
  46 +
  47 + /**
  48 + * config hook
  49 + * @param $callback
  50 + * @return $this
  51 + * @throws \PhpOffice\PhpSpreadsheet\Exception
  52 + */
  53 + public function config($callback)
  54 + {
  55 + if(is_callable($callback)) {
  56 + $callback($this->spreadsheet->getActiveSheet(),$this->spreadsheet);
  57 + }
  58 + return $this;
  59 + }
  60 +
  61 + /**
  62 + * 设置表头
  63 + * @param array $data
  64 + * @return $this
  65 + */
  66 + public function head($map = [])
  67 + {
  68 + $this->head = $map;
  69 + return $this;
  70 + }
  71 +
  72 + /**
  73 + * @param $data
  74 + * @return $this
  75 + */
  76 + public function data($data)
  77 + {
  78 + $this->data = $data;
  79 + return $this;
  80 + }
  81 +
  82 + /**
  83 + * @return false|string
  84 + * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
  85 + * @author zbj
  86 + * @date 2023/5/8
  87 + */
  88 + public function save()
  89 + {
  90 + $file = "export/".date('Y-m-d')."/{$this->name}_" . date('YmdHis') . ".xlsx";
  91 + $filename = public_path('runtime/'.$file);
  92 +
  93 + if (!is_dir(dirname($filename))) {
  94 + @mkdir(dirname($filename),0755, true);
  95 + }
  96 + $this->render();
  97 +
  98 + $writer = new Xlsx($this->spreadsheet);
  99 + $writer->save($filename);
  100 + if(file_exists($filename) && filesize($filename)) {
  101 + return $file;
  102 + }
  103 + return false;
  104 + }
  105 +
  106 +
  107 + /**
  108 + * 进行数据渲染
  109 + * 遍历所有的单元格处理文件,进行数据处理
  110 + * @return $this
  111 + * @author zbj
  112 + * @date 2023/5/8
  113 + */
  114 + protected function render()
  115 + {
  116 +
  117 + $map = [];
  118 + $sheet = $this->spreadsheet->getActiveSheet();
  119 + $i = 0;
  120 + foreach ($this->head as $k=>$title) {
  121 + $chr = chr(65+$i);
  122 + $map[$chr] = $k;
  123 + if(is_array($title)) {
  124 + $title = $title[0];
  125 + }
  126 + $sheet->setCellValue($chr . "1", $title);
  127 + $i++;
  128 + }
  129 + foreach ($this->data as $k=>$item) {
  130 + foreach ($map as $chr => $field) {
  131 + if(is_array($this->head[$field]) && is_callable($this->head[$field][1])) { //TODO 进行字段内容的处理
  132 + $this->head[$field][1]($sheet, $chr . ($k + 2), $item[$field]);
  133 + }
  134 + $sheet->setCellValue($chr . ($k + 2), $this->getDataValue($field, $item));
  135 + }
  136 + }
  137 + return $this;
  138 + }
  139 +
  140 + /**
  141 + * 读取指定字段的value, 支持"."形式指定多维数组
  142 + * @param $name
  143 + * @param $data
  144 + * @return mixed|null
  145 + * @author zbj
  146 + * @date 2023/5/8
  147 + */
  148 + protected function getDataValue($name, $data)
  149 + {
  150 + if(false === strpos($name, '.')) {
  151 + return $data[$name] ?? null;
  152 + }
  153 + $name = explode('.', $name);
  154 + $name[0] = strtolower($name[0]);
  155 +
  156 + // 按.拆分成多维数组进行判断
  157 + foreach ($name as $val) {
  158 + if (isset($data[$val])) {
  159 + $data = $data[$val];
  160 + } else {
  161 + $data = null;
  162 + break;
  163 + }
  164 + }
  165 + return $data;
  166 + }
  167 +}
@@ -13,7 +13,8 @@ @@ -13,7 +13,8 @@
13 "intervention/image": "^2.7", 13 "intervention/image": "^2.7",
14 "laravel/framework": "^8.75", 14 "laravel/framework": "^8.75",
15 "laravel/sanctum": "^2.11", 15 "laravel/sanctum": "^2.11",
16 - "laravel/tinker": "^2.5" 16 + "laravel/tinker": "^2.5",
  17 + "phpoffice/phpspreadsheet": "^1.28"
17 }, 18 },
18 "require-dev": { 19 "require-dev": {
19 "facade/ignition": "^2.5", 20 "facade/ignition": "^2.5",
@@ -58,7 +58,17 @@ return [ @@ -58,7 +58,17 @@ return [
58 'root' => env('UPLOAD_ROOT_PATH') ?: public_path('upload'), 58 'root' => env('UPLOAD_ROOT_PATH') ?: public_path('upload'),
59 'url' => env('UPLOAD_LOCAL_URL') ?: env('APP_URL') . '/upload', 59 'url' => env('UPLOAD_LOCAL_URL') ?: env('APP_URL') . '/upload',
60 'visibility' => 'public', 60 'visibility' => 'public',
61 - ] 61 + ],
  62 +
  63 + 'runtime' => [
  64 + 'driver' => 'local',
  65 + 'root' => public_path('runtime'),
  66 + 'url' => env('APP_URL').'/runtime',
  67 + 'visibility' => 'public',
  68 + ],
  69 +
  70 +
  71 +
62 72
63 ], 73 ],
64 74
@@ -198,6 +198,7 @@ Route::middleware(['bloginauth'])->group(function () { @@ -198,6 +198,7 @@ Route::middleware(['bloginauth'])->group(function () {
198 Route::get('/', [\App\Http\Controllers\Bside\InquiryController::class, 'index'])->name('inquiry'); 198 Route::get('/', [\App\Http\Controllers\Bside\InquiryController::class, 'index'])->name('inquiry');
199 Route::get('/info', [\App\Http\Controllers\Bside\InquiryController::class, 'info'])->name('inquiry_info'); 199 Route::get('/info', [\App\Http\Controllers\Bside\InquiryController::class, 'info'])->name('inquiry_info');
200 Route::any('/delete', [\App\Http\Controllers\Bside\InquiryController::class, 'delete'])->name('inquiry_delete'); 200 Route::any('/delete', [\App\Http\Controllers\Bside\InquiryController::class, 'delete'])->name('inquiry_delete');
  201 + Route::any('/export', [\App\Http\Controllers\Bside\InquiryController::class, 'export'])->name('inquiry_export');
201 }); 202 });
202 203
203 //生成路由 204 //生成路由