- 种菜报销:复用已登记镜像 jiansun.dbo.jst_workOrderInfo,工单类型“种菜报销”、状态已完成, 按完成时间归属报销月份(M 月 = [M-02 00:00, M+1-02 00:00)),自 2026-09-02 起;同一工单只取最新一版 - 种菜损耗:当月种菜报销的线上订单号匹配上月+本月发货数据(jst_oms_shipping)交易单号; 任务备注/卖家备注含“拍A发B/拍A发A”的不扣款(单独导出发运营),只发信誉订单虚拟条码/透明挂钩的不扣款, 其余按发货条码在普通商品资料(ops_jst_sku)的成本价 × 数量 × 1.2 扣款,成本价缺失单独提示 - 两页均支持筛选、列设置、CSV 导出;按月缓存 10 分钟 - 测试:窗口口径、免扣字样、虚拟条码/挂钩、成本价取数与缺失、页面筛选和导出 涉及:金额计算展示(只读);不涉及数据库迁移、权限模型和上游写入。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VANWYsNUbu2piMtCKymoyd
76 lines
2.8 KiB
PHP
76 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Business;
|
|
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\EcommerceFinance\Services\PlantingLossCalculator;
|
|
use Modules\EcommerceFinance\View\PlantingLossPageData;
|
|
use Modules\EcommerceFinance\View\PlantingReimbursementPageData;
|
|
|
|
/** 种菜数据汇总:种菜报销 / 种菜损耗 导出(与页面同一筛选口径)。 */
|
|
class PlantingWorkOrders extends Controller
|
|
{
|
|
public function exportReimbursements(PlantingReimbursementPageData $data)
|
|
{
|
|
$filters = $data->filters();
|
|
|
|
return $this->csv(
|
|
PlantingReimbursementPageData::TITLE . '-' . $filters['month'],
|
|
$data->exportColumns(),
|
|
static fn () => $data->rows($filters),
|
|
);
|
|
}
|
|
|
|
public function exportLoss(PlantingLossPageData $data)
|
|
{
|
|
$filters = $data->filters();
|
|
$suffix = match ($filters['result']) {
|
|
PlantingLossCalculator::RESULT_EXEMPT => '-不扣款拍A发B',
|
|
PlantingLossCalculator::RESULT_FREE_GOODS => '-不扣款虚拟条码挂钩',
|
|
PlantingLossCalculator::RESULT_UNMATCHED => '-未匹配发货',
|
|
'all' => '-全部',
|
|
default => '-扣款',
|
|
};
|
|
|
|
return $this->csv(
|
|
PlantingLossPageData::TITLE . '-' . $filters['month'] . $suffix,
|
|
$data->exportColumns(),
|
|
static fn () => $data->rows($filters),
|
|
);
|
|
}
|
|
|
|
/** @param array<string,string> $columns @param callable():iterable<array<string,mixed>> $rows */
|
|
private function csv(string $name, array $columns, callable $rows)
|
|
{
|
|
$file = tmpfile();
|
|
abort_if($file === false, 500, '无法创建导出文件。');
|
|
|
|
try {
|
|
fwrite($file, "\xEF\xBB\xBF");
|
|
fputcsv($file, array_values($columns));
|
|
foreach ($rows() as $row) {
|
|
$values = [];
|
|
foreach (array_keys($columns) as $key) {
|
|
$values[] = $row[$key] ?? '';
|
|
}
|
|
fputcsv($file, array_map(static function (mixed $value): string {
|
|
$value = (string) $value;
|
|
|
|
// 长数字单号/账号保留文本,避免 Excel 截断;同时阻止公式执行。
|
|
return preg_match('/^[=+\-@\t\r\n]|^\d{12,}$/u', $value) ? "'" . $value : $value;
|
|
}, $values));
|
|
}
|
|
rewind($file);
|
|
} catch (\Throwable $exception) {
|
|
fclose($file);
|
|
report($exception);
|
|
abort(503, '聚工单镜像或发货数据未就绪,未生成不完整的导出文件,请稍后重试。');
|
|
}
|
|
|
|
return response()->streamDownload(static function () use ($file): void {
|
|
fpassthru($file);
|
|
fclose($file);
|
|
}, $name . '-' . now()->format('YmdHis') . '.csv', ['Content-Type' => 'text/csv; charset=UTF-8']);
|
|
}
|
|
}
|