87 lines
3.4 KiB
PHP
87 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace plugin\produce\app\service\admin;
|
|
|
|
use core\base\BaseService;
|
|
use PhpOffice\PhpSpreadsheet\IOFactory;
|
|
use plugin\produce\app\dao\MaterialDao;
|
|
use plugin\produce\app\model\Material;
|
|
use plugin\produce\app\model\MaterialCategory;
|
|
|
|
class MaterialService extends BaseService
|
|
{
|
|
public function __construct(MaterialDao $dao)
|
|
{
|
|
$this->dao = $dao;
|
|
}
|
|
|
|
/**
|
|
* 从 Excel 导入物料;首行必须为:分类、商品编码、商品名称。
|
|
* 相同商品编码会更新分类和名称,以便重复导入。
|
|
*/
|
|
public function importFromExcel(string $filePath): array
|
|
{
|
|
$sheet = IOFactory::load($filePath)->getActiveSheet();
|
|
$rows = $sheet->toArray('', true, true, false);
|
|
if (count($rows) < 2) {
|
|
throw new \InvalidArgumentException('导入文件至少应包含表头和一条物料数据');
|
|
}
|
|
|
|
$headers = array_map(static fn ($value) => trim((string) $value), $rows[0]);
|
|
$indexes = array_flip($headers);
|
|
foreach (['分类', '商品编码', '商品名称'] as $header) {
|
|
if (!array_key_exists($header, $indexes)) {
|
|
throw new \InvalidArgumentException('导入表头必须包含:分类、商品编码、商品名称');
|
|
}
|
|
}
|
|
|
|
return $this->transaction(function () use ($rows, $indexes) {
|
|
$created = 0;
|
|
$updated = 0;
|
|
$categories = [];
|
|
|
|
foreach (array_slice($rows, 1) as $rowNumber => $row) {
|
|
$categoryName = trim((string) ($row[$indexes['分类']] ?? ''));
|
|
$productCode = trim((string) ($row[$indexes['商品编码']] ?? ''));
|
|
$productName = trim((string) ($row[$indexes['商品名称']] ?? ''));
|
|
if ($categoryName === '' && $productCode === '' && $productName === '') {
|
|
continue;
|
|
}
|
|
if ($categoryName === '' || $productCode === '' || $productName === '') {
|
|
throw new \InvalidArgumentException('第 ' . ($rowNumber + 2) . ' 行的分类、商品编码、商品名称均不能为空');
|
|
}
|
|
|
|
$category = $categories[$categoryName] ?? null;
|
|
if (!$category) {
|
|
$category = MaterialCategory::query()->withTrashed()->where('category_name', $categoryName)->first();
|
|
if ($category?->trashed()) {
|
|
$category->restore();
|
|
}
|
|
$category ??= MaterialCategory::query()->create(['category_name' => $categoryName]);
|
|
$categories[$categoryName] = $category;
|
|
}
|
|
$material = Material::query()->withTrashed()->where('product_code', $productCode)->first();
|
|
if ($material) {
|
|
if ($material->trashed()) {
|
|
$material->restore();
|
|
}
|
|
$material->fill(['category_id' => $category->id, 'product_name' => $productName])->save();
|
|
$updated++;
|
|
continue;
|
|
}
|
|
|
|
Material::query()->create([
|
|
'category_id' => $category->id,
|
|
'product_code' => $productCode,
|
|
'product_name' => $productName,
|
|
]);
|
|
$created++;
|
|
}
|
|
|
|
return ['created' => $created, 'updated' => $updated];
|
|
});
|
|
}
|
|
}
|