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.

180 lines
5.6 KiB

3 months ago
<?php
namespace App\Console\Commands;
use App\Models\OrderItems;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
class UpdateOrderFeePercent extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'orders:update-fee-percent';
/**
* The console command description.
*
* @var string
*/
protected $description = '批量修改订单项的管理费比例为15%';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
2 months ago
$filePath = base_path('2026.1.21市一院护工工资免陪护比列更改为15%.xlsx');
3 months ago
if (!file_exists($filePath)) {
$this->error('文件未找到:' . $filePath);
return 1;
}
$this->info('开始读取 Excel 文件...');
try {
// 读取 Excel 文件
$data = Excel::toArray([], $filePath);
if (empty($data) || empty($data[0])) {
$this->error('Excel 文件为空或格式不正确');
return 1;
}
$rows = $data[0];
$headerRow = array_shift($rows); // 移除表头行
// 查找"流水号"列的索引
$serialIndex = array_search('流水号', $headerRow);
if ($serialIndex === false) {
$this->error('未找到"流水号"列');
return 1;
}
$this->info('找到 ' . count($rows) . ' 行数据');
$this->info('开始处理订单项...');
$successCount = 0;
$errorCount = 0;
$notFoundCount = 0;
$totalRows = count($rows);
DB::beginTransaction();
try {
foreach ($rows as $index => $row) {
$rowNumber = $index + 2; // Excel 行号从2开始因为第1行是表头
// 获取流水号订单项ID
$orderItemId = $row[$serialIndex] ?? null;
if (empty($orderItemId)) {
$this->warn("第 {$rowNumber} 行:流水号为空,跳过");
$errorCount++;
continue;
}
// 转换为整数
$orderItemId = (int) $orderItemId;
// 查找订单项,并预先加载必要的关系
$orderItem = OrderItems::with(['order', 'product'])->find($orderItemId);
if (!$orderItem) {
$this->warn("第 {$rowNumber} 行:未找到 ID 为 {$orderItemId} 的订单项,跳过");
$notFoundCount++;
continue;
}
// 解析 factors JSON
$factors = json_decode($orderItem->factors, true);
if (!$factors || !is_array($factors)) {
$this->warn("第 {$rowNumber} 行:订单项 ID {$orderItemId} 的 factors 数据格式不正确,跳过");
$errorCount++;
continue;
}
// 查找并更新管理费比例
$updated = false;
foreach ($factors as &$factor) {
if (!isset($factor['used_for_fee']) || !$factor['used_for_fee']) {
continue;
}
// 直接将 fee_percent 修改为 15
if (isset($factor['fee_percent'])) {
$factor['fee_percent'] = 15;
$updated = true;
}
}
if (!$updated) {
$this->warn("第 {$rowNumber} 行:订单项 ID {$orderItemId} 没有找到用于管理费的因子,跳过");
$errorCount++;
continue;
}
// 更新 factors
$orderItem->factors = json_encode($factors);
// 重新计算管理费
$orderItem->calculateFee();
3 months ago
// 移除非数据库字段factor_texts 是动态属性,不是数据库字段)
unset($orderItem->factor_texts);
3 months ago
// 保存更新
$orderItem->save();
$successCount++;
if ($successCount % 10 == 0) {
$this->info("已处理 {$successCount} 条订单项...");
}
}
DB::commit();
$this->info('');
$this->info('处理完成!');
$this->info("成功:{$successCount} 条");
$this->info("未找到:{$notFoundCount} 条");
$this->info("错误/跳过:{$errorCount} 条");
$this->info("总计:{$totalRows} 行");
return 0;
} catch (\Exception $e) {
DB::rollBack();
$this->error('处理过程中发生错误:' . $e->getMessage());
$this->error('错误位置:' . $e->getFile() . ':' . $e->getLine());
return 1;
}
} catch (\Exception $e) {
$this->error('读取 Excel 文件时发生错误:' . $e->getMessage());
return 1;
}
}
}