海南旅游SAAS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
6.0 KiB

  1. <?php
  2. namespace App\Imports;
  3. use App\Models\Category;
  4. use App\Models\Product;
  5. use Illuminate\Support\Collection;
  6. use Illuminate\Support\Facades\Storage;
  7. use Maatwebsite\Excel\Concerns\ToCollection;
  8. use Maatwebsite\Excel\Facades\Excel;
  9. class ProductImport implements ToCollection
  10. {
  11. private int $supplier_id;
  12. private string $extract_path;
  13. private array $keys = [];
  14. public function __construct(int $supplier_id, $extract_path)
  15. {
  16. $this->supplier_id = $supplier_id;
  17. $this->extract_path = $extract_path;
  18. }
  19. public function collection(Collection $collection)
  20. {
  21. if ($collection->isEmpty()) {
  22. return;
  23. }
  24. //校验数组count()是否正确
  25. if (count($collection[0]) < 35) {
  26. throw new \Exception('Excel产品信息格式不正确');
  27. }
  28. $this->keys = array_flip($collection[0]->toArray());
  29. //去除第一行的标题
  30. unset($collection[0]);
  31. //$collection
  32. $this->createData($collection);
  33. }
  34. private function createData($rows)
  35. {
  36. $keys = $this->keys;
  37. foreach ($rows as $product_index => $row) {
  38. $category = Category::where(['agent_id' => 0, 'name' => trim($row[$keys['分类']])])->first();
  39. if (!$category) continue;
  40. $insert_data = [
  41. 'supplier_id' => $this->supplier_id,
  42. 'category_id' => $category->id,
  43. 'type' => $category->publish_type,
  44. 'title' => $row[$keys['产品标题']] ?? '',
  45. 'price' => $row[$keys['销售价']] ?? 0,
  46. 'original_price' => $row[$keys['市场价']] ?? 0,
  47. 'stock' => $row[$keys['库存']] ?? 0,
  48. 'know' => $row[$keys['旅客须知']] ?? '',
  49. 'content' => $row[$keys['产品详情']] ?? '',
  50. 'verify_mobile' => $row[$keys['核销手机号']] ?? '',
  51. 'diy_form_id' => $row[$keys['信息收集表单ID']] ?? '',
  52. 'pictures' => $this->get_pictures($product_index),
  53. ];
  54. # 扩展字段
  55. $insert_data['extends'] = $this->get_extends($category->publish_type, $row);
  56. if ($category->publish_type == 0) {
  57. $insert_data['longitude'] = $insert_data['extends']['field_0_departure_place_longitude'] ?? 0;
  58. $insert_data['latitude'] = $insert_data['extends']['field_0_departure_place_latitude'] ?? 0;
  59. $insert_data['address'] = $insert_data['extends']['field_0_departure_place'] ?? '';
  60. } else {
  61. $insert_data['longitude'] = $insert_data['extends']['field_'.$category->publish_type.'_longitude'] ?? 0;
  62. $insert_data['latitude'] = $insert_data['extends']['field_'.$category->publish_type.'_latitude'] ?? 0;
  63. $insert_data['address'] = $insert_data['extends']['field_'.$category->publish_type.'_address'] ?? '';
  64. }
  65. $product = Product::create($insert_data);
  66. if ($product->id) {
  67. $this->insert_spec($product_index, $product->id);
  68. }
  69. }
  70. }
  71. # 插入规格
  72. private function insert_spec($product_index, $product_id)
  73. {
  74. $spec_file = $this->extract_path . "/产品规格{$product_index}.xlsx";
  75. if (file_exists($spec_file)) {
  76. Excel::import(new ProductSpecImport($product_id), $spec_file);
  77. }
  78. }
  79. # 遍历图片文件,并移动到storage/app/public/supplier/import目录下
  80. private function get_pictures($product_index): array
  81. {
  82. $storage_disk = Storage::disk('public');
  83. $http_path = 'supplier/import/' . $this->supplier_id . '/' . date('Y-m');
  84. if (!$storage_disk->exists($http_path)) {
  85. $storage_disk->makeDirectory($http_path); //Storage的makeDirectory才能递归创建
  86. }
  87. $image_path = $this->extract_path . "/产品主图/$product_index";
  88. chdir($image_path);
  89. $pictures = [];
  90. foreach (glob('*') as $file) {
  91. $ext = strtolower(pathinfo($file)['extension']);
  92. if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'jfif'])) {
  93. continue;
  94. }
  95. $filename = '/' . md5_file($file) . '.' . $ext;
  96. $move_file = realpath($file);
  97. # Storage::move只适用于storage/app目录下的文件,且是相对路径
  98. if (rename($move_file, $storage_disk->path($http_path . $filename))) {
  99. $pictures[] = $http_path . $filename;
  100. }
  101. }
  102. return $pictures;
  103. }
  104. # 获取扩展字段
  105. private function get_extends(int $publish_type, $row): array
  106. {
  107. $keys = $this->keys;
  108. return match ($publish_type) {
  109. 0 => [
  110. 'field_0_departure_place' => $row[$keys['出发地']] ?? '',
  111. 'field_0_departure_place_longitude' => $row[$keys['出发地经度']] ?? 0,
  112. 'field_0_departure_place_latitude' => $row[$keys['出发地纬度']] ?? 0,
  113. 'field_0_destination' => $row[$keys['目的地']] ?? '',
  114. 'field_0_destination_longitude' => $row[$keys['目的地经度']] ?? 0,
  115. 'field_0_destination_latitude' => $row[$keys['目的地纬度']] ?? 0,
  116. 'field_0_date' => [
  117. # Excel日期是从1900-01-01起,PHP日期是1970-01-01起,所以要减去25569天数得到正确日期
  118. 'start' => !empty($row[$keys['行程起始时间']]) ? date('Y-m-d', strtotime('+ ' . ($row[$keys['行程起始时间']] - 25569) . 'day', 0)) : '',
  119. 'end' => !empty($row[$keys['行程结束时间']]) ? date('Y-m-d', strtotime('+ ' . ($row[$keys['行程结束时间']] - 25569) . 'day', 0)) : '',
  120. ],
  121. ],
  122. 1 => [
  123. 'field_1_name' => $row[$keys['酒店名']] ?? '',
  124. 'field_1_address' => $row[$keys['酒店地址']] ?? '',
  125. 'field_1_longitude' => $row[$keys['酒店经度']] ?? 0,
  126. 'field_1_latitude' => $row[$keys['酒店纬度']] ?? 0,
  127. ],
  128. 2 => [
  129. 'field_2_name' => $row[$keys['景区名']] ?? '',
  130. 'field_2_address' => $row[$keys['景区地址']] ?? '',
  131. 'field_2_longitude' => $row[$keys['景区经度']] ?? 0,
  132. 'field_2_latitude' => $row[$keys['景区纬度']] ?? 0,
  133. ],
  134. 3 => [
  135. 'field_3_name' => $row[$keys['餐厅名']] ?? '',
  136. 'field_3_address' => $row[$keys['餐厅地址']] ?? '',
  137. 'field_3_longitude' => $row[$keys['餐厅经度']] ?? 0,
  138. 'field_3_latitude' => $row[$keys['餐厅纬度']] ?? 0,
  139. ],
  140. 4 => [
  141. 'field_4_address' => $row[$keys['交通地址']] ?? '',
  142. 'field_4_longitude' => $row[$keys['交通经度']] ?? 0,
  143. 'field_4_latitude' => $row[$keys['交通纬度']] ?? 0,
  144. ],
  145. 5 => [
  146. 'field_5_address' => $row[$keys['购物地址']] ?? '',
  147. 'field_5_longitude' => $row[$keys['购物经度']] ?? 0,
  148. 'field_5_latitude' => $row[$keys['购物纬度']] ?? 0,
  149. ],
  150. default => [],
  151. };
  152. }
  153. }