Kimi chinh sua

This commit is contained in:
2026-04-24 08:58:53 +00:00
parent 91ff4a5e4d
commit 86216ef872
43 changed files with 2868 additions and 597 deletions

View File

@@ -0,0 +1,118 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Project;
use App\Models\Product;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Illuminate\Support\Str;
class ImportProductsExcel extends Command
{
protected $signature = 'import:products-excel {file=sanpham.xlsx}';
protected $description = 'Import sản phẩm từ file Excel vào dự án Hà Quang 1';
public function handle()
{
$filePath = $this->argument('file');
if (!file_exists($filePath)) {
$this->error("Không tìm thấy file: {$filePath}");
return 1;
}
$this->info("Đang đọc file Excel...");
$spreadsheet = IOFactory::load($filePath);
$worksheet = $spreadsheet->getActiveSheet();
$rows = $worksheet->toArray();
// 1. Đảm bảo có dự án Hà Quang 1
$project = Project::firstOrCreate(
['name' => 'Hà Quang 1'],
['code' => 'HQ1']
);
$this->info("Dự án: {$project->name} (ID: {$project->id})");
// 2. Duyệt dữ liệu (bỏ qua dòng tiêu đề)
$count = 0;
foreach ($rows as $index => $row) {
if ($index === 0 || empty($row[2])) continue; // Bỏ qua header hoặc dòng trống mã lô
$code = $row[2];
// Chuẩn hóa số
$area = (float) $row[3];
$price_per_unit = $this->parseMoney($row[4]);
$total_price = $this->parseMoney($row[5]);
$qsdd_value = $this->parseMoney($row[6]);
$foundation_temp_value = $this->parseMoney($row[7]);
$contract_temp_value = $this->parseMoney($row[8]);
// Phân tách hạ tầng (JSONB)
$infraRaw = $row[14] ?? '';
$infraJson = $this->parseInfrastructure($infraRaw);
// Custom data
$customData = [
'block' => $row[1],
'building_density' => $row[12],
'legal_status_raw' => $row[15],
'summary_legal' => $row[19],
];
Product::updateOrCreate(
['code' => $code, 'project_id' => $project->id],
[
'product_type' => 'LAND', // Mặc định là đất nền theo file
'area' => $area,
'price_per_unit' => $price_per_unit,
'total_price' => $total_price,
'qsdd_value' => $qsdd_value,
'foundation_temp_value' => $foundation_temp_value,
'contract_temp_value' => $contract_temp_value,
'adjacent_road' => $row[9],
'frontage_count' => (int) $row[10],
'max_floors' => (int) $row[11],
'construction_status' => $row[13] ?? 'Chưa xây dựng',
'infrastructure_status' => $infraJson,
'custom_data' => $customData,
'status' => 'Đang mở bán',
]
);
$count++;
if ($count % 10 === 0) $this->line("Đã import: {$count} sản phẩm...");
}
$this->info("Thành công! Đã import tổng cộng {$count} sản phẩm vào dự án Hà Quang 1.");
return 0;
}
private function parseMoney($value)
{
if (empty($value)) return 0;
// Xóa dấu phẩy và khoảng trắng
return (float) str_replace([',', ' '], '', $value);
}
private function parseInfrastructure($raw)
{
if (empty($raw)) return [];
$result = [];
// Tách theo dấu gạch ngang " - "
$parts = explode(' - ', $raw);
foreach ($parts as $part) {
// Tách theo dấu hai chấm ":"
$subParts = explode(':', $part, 2);
if (count($subParts) === 2) {
$key = trim($subParts[0]);
$value = trim($subParts[1]);
$result[$key] = $value;
}
}
return $result;
}
}