94 lines
4.3 KiB
PHP
94 lines
4.3 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Business;
|
||
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Routing\Controller;
|
||
use Modules\EcommerceFinance\Services\AccessoryReshipCourierImporter;
|
||
use Modules\EcommerceFinance\Services\AccessoryReshipCourierStore;
|
||
use Modules\EcommerceFinance\Services\AccessoryReshipRateCalculator;
|
||
use Modules\EcommerceFinance\View\AccessoryReshipConfigPageData;
|
||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||
|
||
class AccessoryReshipCourierConfigs extends Controller
|
||
{
|
||
public function __construct(private readonly AccessoryReshipCourierStore $store) {}
|
||
|
||
public function store(Request $request)
|
||
{
|
||
$this->store->save((int) company_id(), $this->validated($request), $this->actor());
|
||
return $this->back('快递扣款配置已新增。');
|
||
}
|
||
|
||
public function update(Request $request, int $configId)
|
||
{
|
||
$this->store->save((int) company_id(), $this->validated($request), $this->actor(), $configId);
|
||
return $this->back('快递扣款配置已更新,核对清单将按新比例重新计算。');
|
||
}
|
||
|
||
public function destroy(int $configId)
|
||
{
|
||
$this->store->changeDeleted((int) company_id(), $configId, true, $this->actor());
|
||
return $this->back('配置已删除,该快递暂不参与扣款计算。');
|
||
}
|
||
|
||
public function restore(int $configId)
|
||
{
|
||
$this->store->changeDeleted((int) company_id(), $configId, false, $this->actor());
|
||
return $this->back('快递扣款配置已恢复。');
|
||
}
|
||
|
||
public function import(Request $request, AccessoryReshipCourierImporter $importer)
|
||
{
|
||
$request->validate(['file' => ['required', 'file', 'mimes:xlsx', 'max:10240']]);
|
||
$path = $request->file('file')->getRealPath();
|
||
$rows = $importer->read($path);
|
||
$result = $this->store->import((int) company_id(), $rows, $this->actor(), hash_file('sha256', $path));
|
||
return $this->back("导入完成:新增{$result['added']}条,重复跳过{$result['skipped']}条。");
|
||
}
|
||
|
||
public function export(AccessoryReshipConfigPageData $data)
|
||
{
|
||
$rows = $this->store->filtered((int) company_id(), $data->filters())->get();
|
||
$book = new Spreadsheet();
|
||
$sheet = $book->getActiveSheet();
|
||
$sheet->setTitle('快递配置');
|
||
$sheet->fromArray([['快递代码', '快递公司', '创建时间', '创建人', '扣款比率(%)', '删除状态']]);
|
||
foreach ($rows as $index => $row) {
|
||
$number = $index + 2;
|
||
foreach ([$row->courier_code, $row->courier_name, $row->source_created_at ?: $row->created_at, $row->creator] as $column => $value) {
|
||
$sheet->setCellValueExplicit([$column + 1, $number], (string) $value, DataType::TYPE_STRING);
|
||
}
|
||
$sheet->setCellValue([5, $number], $row->rate_basis_points / 10000);
|
||
$sheet->getStyle('E' . $number)->getNumberFormat()->setFormatCode('0.00%');
|
||
$sheet->setCellValueExplicit([6, $number], $row->deleted_at ? '已删除' : '正常', DataType::TYPE_STRING);
|
||
}
|
||
foreach (['A' => 24, 'B' => 30, 'C' => 24, 'D' => 18, 'E' => 18, 'F' => 14] as $column => $width) {
|
||
$sheet->getColumnDimension($column)->setWidth($width);
|
||
}
|
||
$sheet->freezePane('A2');
|
||
return response()->streamDownload(function () use ($book): void {
|
||
try { (new Xlsx($book))->save('php://output'); } finally { $book->disconnectWorksheets(); }
|
||
}, '快递扣款配置.xlsx', ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||
}
|
||
|
||
private function validated(Request $request): array
|
||
{
|
||
$data = $request->validate(['courier_code' => ['required', 'string', 'max:64'], 'courier_name' => ['required', 'string', 'max:191'], 'rate_percent' => ['required', 'string']]);
|
||
$data['rate_basis_points'] = AccessoryReshipRateCalculator::basisPoints($data['rate_percent']);
|
||
return $data;
|
||
}
|
||
|
||
private function actor(): string
|
||
{
|
||
return mb_substr((string) user()->name, 0, 191);
|
||
}
|
||
|
||
private function back(string $message)
|
||
{
|
||
return redirect()->route('business.pages.show', ['section' => 'courier-payables', 'page' => 'accessory-reship-deductions', 'reship_view' => 'config'])->with('reship_config_message', $message);
|
||
}
|
||
}
|