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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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()
{
$filePath = base_path('2026.1.21市一院护工工资免陪护比列更改为15%.xlsx');
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();
// 移除非数据库字段factor_texts 是动态属性,不是数据库字段)
unset($orderItem->factor_texts);
// 保存更新
$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;
}
}
}