9 changed files with 875 additions and 0 deletions
@ -0,0 +1,18 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Exports; |
||||
|
|
||||
|
use App\Models\AdminVipList; |
||||
|
use Illuminate\Database\Eloquent\Collection; |
||||
|
use Maatwebsite\Excel\Concerns\FromCollection; |
||||
|
|
||||
|
class AdminVipListExport implements FromCollection |
||||
|
{ |
||||
|
/** |
||||
|
* @return Collection |
||||
|
*/ |
||||
|
public function collection(): Collection |
||||
|
{ |
||||
|
return AdminVipList::all(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Exports; |
||||
|
|
||||
|
use Maatwebsite\Excel\Concerns\FromCollection; |
||||
|
|
||||
|
class AdminVipListImportTemplateExport implements FromCollection |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function collection(): array |
||||
|
{ |
||||
|
return [ |
||||
|
[__('exports.vip_list.license')], |
||||
|
['粤B88888'] |
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,260 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Http\Controllers\Admin; |
||||
|
|
||||
|
use App\Exceptions\CustomException; |
||||
|
use App\Exports\AdminVipListExport; |
||||
|
use App\Exports\AdminVipListImportTemplateExport; |
||||
|
use App\Imports\AdminVipListImport; |
||||
|
use App\Models\AdminUsers; |
||||
|
use App\Models\AdminVipList; |
||||
|
use App\Services\AdminVipListService; |
||||
|
use App\Services\ApiResponseService; |
||||
|
use Exception; |
||||
|
use Illuminate\Http\JsonResponse; |
||||
|
use Illuminate\Http\Request; |
||||
|
use Illuminate\Support\Facades\Storage; |
||||
|
use Illuminate\Support\Facades\Validator; |
||||
|
use Illuminate\Validation\ValidationException; |
||||
|
use Maatwebsite\Excel\Facades\Excel; |
||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse; |
||||
|
|
||||
|
class VipListController extends BaseController |
||||
|
{ |
||||
|
/** |
||||
|
* @var ApiResponseService |
||||
|
*/ |
||||
|
protected ApiResponseService $responseService; |
||||
|
|
||||
|
/** |
||||
|
* @var AdminVipListService |
||||
|
*/ |
||||
|
protected AdminVipListService $vipListService; |
||||
|
|
||||
|
/** |
||||
|
* @param ApiResponseService $responseService |
||||
|
* @param AdminVipListService $vipListService |
||||
|
*/ |
||||
|
public function __construct( |
||||
|
ApiResponseService $responseService, |
||||
|
AdminVipListService $vipListService |
||||
|
) { |
||||
|
$this->responseService = $responseService; |
||||
|
$this->vipListService = $vipListService; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param Request $request |
||||
|
* @return JsonResponse |
||||
|
*/ |
||||
|
public function index(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$query = AdminVipList::query(); |
||||
|
|
||||
|
// 分页 |
||||
|
$page = $request->input('page', 1); |
||||
|
$perPage = $request->input('per_page', 10); |
||||
|
|
||||
|
$total = $query->count(); |
||||
|
$items = $query->latest()->forPage($page, $perPage)->get()->each( |
||||
|
function ($item) { |
||||
|
$item['username'] = AdminUsers::getUsername( |
||||
|
$item['user_id'] |
||||
|
); |
||||
|
return $item; |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
return $this->responseService->success([ |
||||
|
'items' => $items, |
||||
|
'total' => $total, |
||||
|
'page' => $page, |
||||
|
'per_page' => $perPage, |
||||
|
'last_page' => ceil($total / $perPage), |
||||
|
]); |
||||
|
} catch (Exception $e) { |
||||
|
$m_prefix = __('exception.get_user_info_list_failed'); |
||||
|
return $this->responseService->systemError( |
||||
|
$m_prefix . ':' . $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param Request $request |
||||
|
* @param string $id |
||||
|
* @return JsonResponse |
||||
|
* @throws CustomException |
||||
|
* @throws ValidationException |
||||
|
*/ |
||||
|
public function update(Request $request, string $id): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$this->saveValidator($request->all(), $id); |
||||
|
$this->vipListService->updateModel($request->all(), $id); |
||||
|
return $this->responseService->success( |
||||
|
null, |
||||
|
__('admin.update_succeeded') |
||||
|
); |
||||
|
} catch (ValidationException|CustomException $e) { |
||||
|
throw $e; |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.admin_vip_list.update_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param array $data |
||||
|
* @param int $id |
||||
|
* @return void |
||||
|
* @throws ValidationException |
||||
|
*/ |
||||
|
protected function saveValidator(array $data, int $id = 0): void |
||||
|
{ |
||||
|
$rules = [ |
||||
|
'license' => 'required|max:20' |
||||
|
]; |
||||
|
$messages = [ |
||||
|
'license.required' => __('validation.admin_list_vip.l_empty'), |
||||
|
'license.max' => __('validation.admin_list_vip.l_max') |
||||
|
]; |
||||
|
if ($id) { |
||||
|
$this->validateId($id, AdminVipList::class); |
||||
|
} |
||||
|
$validator = Validator::make($data, $rules, $messages); |
||||
|
|
||||
|
if ($validator->fails()) { |
||||
|
throw new ValidationException($validator); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $id |
||||
|
* @return JsonResponse |
||||
|
* @throws CustomException |
||||
|
* @throws ValidationException |
||||
|
*/ |
||||
|
public function destroy(string $id): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$this->validateId($id, AdminVipList::class); |
||||
|
$this->vipListService->deleteModel($id); |
||||
|
return $this->responseService->success( |
||||
|
null, |
||||
|
__('admin.delete_succeeded') |
||||
|
); |
||||
|
} catch (ValidationException|CustomException $e) { |
||||
|
throw $e; |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.admin_vip_list.destroy_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param Request $request |
||||
|
* @return JsonResponse |
||||
|
* @throws ValidationException |
||||
|
*/ |
||||
|
public function import(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
// 1. 验证上传的文件 |
||||
|
$request->validate([ |
||||
|
'file' => 'required|mimes:xlsx,xls,csv|max:2048' // 限制文件类型和大小 |
||||
|
]); |
||||
|
$validator = Validator::make($request->file('file'), [ |
||||
|
'file' => 'required|mimes:xlsx,xls,csv|max:2048' |
||||
|
], [ |
||||
|
'file.required' => __('validation.admin_list_vip.file_empty'), |
||||
|
'file.mimes' => __('validation.admin_list_vip.file_mimes'), |
||||
|
'file.max' => __('validation.admin_list_vip.file_max'), |
||||
|
]); |
||||
|
if ($validator->fails()) { |
||||
|
throw new ValidationException($validator); |
||||
|
} |
||||
|
|
||||
|
// 2. 获取上传的文件 |
||||
|
$file = $request->file('file'); |
||||
|
|
||||
|
// 3. 正确的做法:先存储文件,再获取绝对路径进行导入 |
||||
|
// 将文件存储到 storage/app/imports 目录下 |
||||
|
$path = $file->store('imports'); |
||||
|
|
||||
|
// 4. 执行导入(使用存储后的绝对路径) |
||||
|
// storage_path('app') 获取 storage/app 的绝对路径 |
||||
|
Excel::import( |
||||
|
new AdminVipListImport(), |
||||
|
storage_path('app/' . $path) |
||||
|
); |
||||
|
|
||||
|
// 5. (可选)导入完成后删除临时文件 |
||||
|
Storage::delete($path); |
||||
|
|
||||
|
return $this->responseService->systemError( |
||||
|
__('controller.import.success') |
||||
|
); |
||||
|
} catch (ValidationException $e) { |
||||
|
throw $e; |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.admin_vip_list.import_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param Request $request |
||||
|
* @return JsonResponse |
||||
|
* @throws CustomException |
||||
|
* @throws ValidationException |
||||
|
*/ |
||||
|
public function store(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$this->saveValidator($request->all()); |
||||
|
$this->vipListService->createModel($request->all()); |
||||
|
|
||||
|
return $this->responseService->success( |
||||
|
null, |
||||
|
__('admin.save_succeeded') |
||||
|
); |
||||
|
} catch (ValidationException|CustomException $e) { |
||||
|
throw $e; |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.admin_vip_list.create_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return BinaryFileResponse |
||||
|
*/ |
||||
|
public function importTemplate(): BinaryFileResponse |
||||
|
{ |
||||
|
return Excel::download( |
||||
|
new AdminVipListImportTemplateExport(), |
||||
|
__('exports.vip_list.import_template') . '.xlsx' |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return BinaryFileResponse |
||||
|
*/ |
||||
|
public function export(): BinaryFileResponse |
||||
|
{ |
||||
|
return Excel::download( |
||||
|
new AdminVipListExport(), |
||||
|
__('exports.vip_list.list') . '.xlsx' |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Imports; |
||||
|
|
||||
|
use App\Models\AdminVipList; |
||||
|
use Illuminate\Support\Facades\Auth; |
||||
|
use Maatwebsite\Excel\Concerns\ToModel; |
||||
|
use Maatwebsite\Excel\Concerns\WithHeadingRow; |
||||
|
|
||||
|
class AdminVipListImport implements ToModel, WithHeadingRow |
||||
|
{ |
||||
|
/** |
||||
|
* @param array $row |
||||
|
* @return AdminVipList |
||||
|
*/ |
||||
|
public function model(array $row): AdminVipList |
||||
|
{ |
||||
|
return new AdminVipList([ |
||||
|
'license' => $row['license'], |
||||
|
'user_id' => Auth::guard('sanctum')->user()['id'], |
||||
|
'created_at' => get_datetime() |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Models; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Database\Eloquent\SoftDeletes; |
||||
|
|
||||
|
class AdminVipList extends Model |
||||
|
{ |
||||
|
use HasFactory, SoftDeletes; |
||||
|
|
||||
|
protected $table = 'admin_vip_list'; |
||||
|
|
||||
|
protected $fillable = [ |
||||
|
'license', |
||||
|
'user_id' |
||||
|
]; |
||||
|
|
||||
|
protected $hidden = [ |
||||
|
'deleted_at', |
||||
|
'updated_at', |
||||
|
'created_at' |
||||
|
]; |
||||
|
} |
||||
@ -0,0 +1,131 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Services; |
||||
|
|
||||
|
use App\Models\AdminVipList; |
||||
|
use Exception; |
||||
|
use Illuminate\Database\Eloquent\Builder; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Support\Facades\Auth; |
||||
|
use Illuminate\Support\Facades\DB; |
||||
|
|
||||
|
class AdminVipListService |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @var OperationLogService |
||||
|
*/ |
||||
|
private OperationLogService $logService; |
||||
|
|
||||
|
/** |
||||
|
* 构造函数 |
||||
|
* @param OperationLogService $logService |
||||
|
*/ |
||||
|
public function __construct(OperationLogService $logService) |
||||
|
{ |
||||
|
$this->logService = $logService; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @param array $data |
||||
|
* @return Model|Builder |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public function createModel(array $data): Model|Builder |
||||
|
{ |
||||
|
try { |
||||
|
DB::beginTransaction(); |
||||
|
|
||||
|
if (AdminVipList::query()->where('license', $data['license']) |
||||
|
->exists() |
||||
|
) { |
||||
|
throw new Exception( |
||||
|
__('service.admin_vip_list.license_exists') |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
$model = AdminVipList::query()->create([ |
||||
|
'license' => $data['license'], |
||||
|
'user_id' => Auth::guard('sanctum')->user()['id'], |
||||
|
'created_at' => get_datetime() |
||||
|
]); |
||||
|
|
||||
|
$this->logService->logCreated($model, '创建VIP名单'); |
||||
|
|
||||
|
DB::commit(); |
||||
|
return $model; |
||||
|
} catch (Exception $e) { |
||||
|
DB::rollBack(); |
||||
|
throw $e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @param array $data |
||||
|
* @param int $id |
||||
|
* @return Model|Builder |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public function updateModel(array $data, int $id): Model|Builder |
||||
|
{ |
||||
|
try { |
||||
|
DB::beginTransaction(); |
||||
|
|
||||
|
// 验证 |
||||
|
$existsWhere = [ |
||||
|
['license', '=', $data['license']], |
||||
|
['id', '<>', $id] |
||||
|
]; |
||||
|
if (AdminVipList::query()->where($existsWhere)->exists()) { |
||||
|
throw new Exception(__('service.admin_vip_list.license_exists')); |
||||
|
} |
||||
|
|
||||
|
// 更新 |
||||
|
$model = AdminVipList::query()->findOrFail($id); |
||||
|
$oldValues = $model->toArray(); |
||||
|
|
||||
|
$model->update([ |
||||
|
'license' => $data['license'], |
||||
|
'user_id' => Auth::guard('sanctum')->user()['id'], |
||||
|
'updated_at' => get_datetime() |
||||
|
]); |
||||
|
|
||||
|
$this->logService->logUpdated($model, $oldValues, '更新VIP名单'); |
||||
|
|
||||
|
DB::commit(); |
||||
|
return $model; |
||||
|
} catch (Exception $e) { |
||||
|
DB::rollBack(); |
||||
|
throw $e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param $id |
||||
|
* @return bool |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public function deleteModel($id): bool |
||||
|
{ |
||||
|
try { |
||||
|
DB::beginTransaction(); |
||||
|
|
||||
|
$model = AdminVipList::query()->findOrFail($id); |
||||
|
|
||||
|
$this->logService->logDeleted($model, '删除VIP名单'); |
||||
|
|
||||
|
$model->delete(); |
||||
|
|
||||
|
DB::commit(); |
||||
|
return true; |
||||
|
} catch (Exception $e) { |
||||
|
DB::rollBack(); |
||||
|
throw $e; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,380 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Maatwebsite\Excel\Excel; |
||||
|
use PhpOffice\PhpSpreadsheet\Reader\Csv; |
||||
|
|
||||
|
return [ |
||||
|
'exports' => [ |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Chunk size |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When using FromQuery, the query is automatically chunked. |
||||
|
| Here you can specify how big the chunk should be. |
||||
|
| |
||||
|
*/ |
||||
|
'chunk_size' => 1000, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Pre-calculate formulas during export |
||||
|
|-------------------------------------------------------------------------- |
||||
|
*/ |
||||
|
'pre_calculate_formulas' => false, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Enable strict null comparison |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When enabling strict null comparison empty cells ('') will |
||||
|
| be added to the sheet. |
||||
|
*/ |
||||
|
'strict_null_comparison' => false, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| CSV Settings |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure e.g. delimiter, enclosure and line ending for CSV exports. |
||||
|
| |
||||
|
*/ |
||||
|
'csv' => [ |
||||
|
'delimiter' => ',', |
||||
|
'enclosure' => '"', |
||||
|
'line_ending' => PHP_EOL, |
||||
|
'use_bom' => false, |
||||
|
'include_separator_line' => false, |
||||
|
'excel_compatibility' => false, |
||||
|
'output_encoding' => '', |
||||
|
'test_auto_detect' => true, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Worksheet properties |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure e.g. default title, creator, subject,... |
||||
|
| |
||||
|
*/ |
||||
|
'properties' => [ |
||||
|
'creator' => '', |
||||
|
'lastModifiedBy' => '', |
||||
|
'title' => '', |
||||
|
'description' => '', |
||||
|
'subject' => '', |
||||
|
'keywords' => '', |
||||
|
'category' => '', |
||||
|
'manager' => '', |
||||
|
'company' => '', |
||||
|
], |
||||
|
], |
||||
|
|
||||
|
'imports' => [ |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Read Only |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When dealing with imports, you might only be interested in the |
||||
|
| data that the sheet exists. By default we ignore all styles, |
||||
|
| however if you want to do some logic based on style data |
||||
|
| you can enable it by setting read_only to false. |
||||
|
| |
||||
|
*/ |
||||
|
'read_only' => true, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Ignore Empty |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When dealing with imports, you might be interested in ignoring |
||||
|
| rows that have null values or empty strings. By default rows |
||||
|
| containing empty strings or empty values are not ignored but can be |
||||
|
| ignored by enabling the setting ignore_empty to true. |
||||
|
| |
||||
|
*/ |
||||
|
'ignore_empty' => false, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Heading Row Formatter |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure the heading row formatter. |
||||
|
| Available options: none|slug|custom |
||||
|
| |
||||
|
*/ |
||||
|
'heading_row' => [ |
||||
|
'formatter' => 'slug', |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| CSV Settings |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure e.g. delimiter, enclosure and line ending for CSV imports. |
||||
|
| |
||||
|
*/ |
||||
|
'csv' => [ |
||||
|
'delimiter' => null, |
||||
|
'enclosure' => '"', |
||||
|
'escape_character' => '\\', |
||||
|
'contiguous' => false, |
||||
|
'input_encoding' => Csv::GUESS_ENCODING, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Worksheet properties |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure e.g. default title, creator, subject,... |
||||
|
| |
||||
|
*/ |
||||
|
'properties' => [ |
||||
|
'creator' => '', |
||||
|
'lastModifiedBy' => '', |
||||
|
'title' => '', |
||||
|
'description' => '', |
||||
|
'subject' => '', |
||||
|
'keywords' => '', |
||||
|
'category' => '', |
||||
|
'manager' => '', |
||||
|
'company' => '', |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Cell Middleware |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure middleware that is executed on getting a cell value |
||||
|
| |
||||
|
*/ |
||||
|
'cells' => [ |
||||
|
'middleware' => [ |
||||
|
//\Maatwebsite\Excel\Middleware\TrimCellValue::class, |
||||
|
//\Maatwebsite\Excel\Middleware\ConvertEmptyCellValuesToNull::class, |
||||
|
], |
||||
|
], |
||||
|
|
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Extension detector |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure here which writer/reader type should be used when the package |
||||
|
| needs to guess the correct type based on the extension alone. |
||||
|
| |
||||
|
*/ |
||||
|
'extension_detector' => [ |
||||
|
'xlsx' => Excel::XLSX, |
||||
|
'xlsm' => Excel::XLSX, |
||||
|
'xltx' => Excel::XLSX, |
||||
|
'xltm' => Excel::XLSX, |
||||
|
'xls' => Excel::XLS, |
||||
|
'xlt' => Excel::XLS, |
||||
|
'ods' => Excel::ODS, |
||||
|
'ots' => Excel::ODS, |
||||
|
'slk' => Excel::SLK, |
||||
|
'xml' => Excel::XML, |
||||
|
'gnumeric' => Excel::GNUMERIC, |
||||
|
'htm' => Excel::HTML, |
||||
|
'html' => Excel::HTML, |
||||
|
'csv' => Excel::CSV, |
||||
|
'tsv' => Excel::TSV, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| PDF Extension |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Configure here which Pdf driver should be used by default. |
||||
|
| Available options: Excel::MPDF | Excel::TCPDF | Excel::DOMPDF |
||||
|
| |
||||
|
*/ |
||||
|
'pdf' => Excel::DOMPDF, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Value Binder |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| PhpSpreadsheet offers a way to hook into the process of a value being |
||||
|
| written to a cell. In there some assumptions are made on how the |
||||
|
| value should be formatted. If you want to change those defaults, |
||||
|
| you can implement your own default value binder. |
||||
|
| |
||||
|
| Possible value binders: |
||||
|
| |
||||
|
| [x] Maatwebsite\Excel\DefaultValueBinder::class |
||||
|
| [x] PhpOffice\PhpSpreadsheet\Cell\StringValueBinder::class |
||||
|
| [x] PhpOffice\PhpSpreadsheet\Cell\AdvancedValueBinder::class |
||||
|
| |
||||
|
*/ |
||||
|
'value_binder' => [ |
||||
|
'default' => Maatwebsite\Excel\DefaultValueBinder::class, |
||||
|
], |
||||
|
|
||||
|
'cache' => [ |
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Default cell caching driver |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| By default PhpSpreadsheet keeps all cell values in memory, however when |
||||
|
| dealing with large files, this might result into memory issues. If you |
||||
|
| want to mitigate that, you can configure a cell caching driver here. |
||||
|
| When using the illuminate driver, it will store each value in the |
||||
|
| cache store. This can slow down the process, because it needs to |
||||
|
| store each value. You can use the "batch" store if you want to |
||||
|
| only persist to the store when the memory limit is reached. |
||||
|
| |
||||
|
| Drivers: memory|illuminate|batch |
||||
|
| |
||||
|
*/ |
||||
|
'driver' => 'memory', |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Batch memory caching |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When dealing with the "batch" caching driver, it will only |
||||
|
| persist to the store when the memory limit is reached. |
||||
|
| Here you can tweak the memory limit to your liking. |
||||
|
| |
||||
|
*/ |
||||
|
'batch' => [ |
||||
|
'memory_limit' => 60000, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Illuminate cache |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When using the "illuminate" caching driver, it will automatically use |
||||
|
| your default cache store. However if you prefer to have the cell |
||||
|
| cache on a separate store, you can configure the store name here. |
||||
|
| You can use any store defined in your cache config. When leaving |
||||
|
| at "null" it will use the default store. |
||||
|
| |
||||
|
*/ |
||||
|
'illuminate' => [ |
||||
|
'store' => null, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Cache Time-to-live (TTL) |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| The TTL of items written to cache. If you want to keep the items cached |
||||
|
| indefinitely, set this to null. Otherwise, set a number of seconds, |
||||
|
| a \DateInterval, or a callable. |
||||
|
| |
||||
|
| Allowable types: callable|\DateInterval|int|null |
||||
|
| |
||||
|
*/ |
||||
|
'default_ttl' => 10800, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Transaction Handler |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| By default the import is wrapped in a transaction. This is useful |
||||
|
| for when an import may fail and you want to retry it. With the |
||||
|
| transactions, the previous import gets rolled-back. |
||||
|
| |
||||
|
| You can disable the transaction handler by setting this to null. |
||||
|
| Or you can choose a custom made transaction handler here. |
||||
|
| |
||||
|
| Supported handlers: null|db |
||||
|
| |
||||
|
*/ |
||||
|
'transactions' => [ |
||||
|
'handler' => 'db', |
||||
|
'db' => [ |
||||
|
'connection' => null, |
||||
|
], |
||||
|
], |
||||
|
|
||||
|
'temporary_files' => [ |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Local Temporary Path |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When exporting and importing files, we use a temporary file, before |
||||
|
| storing reading or downloading. Here you can customize that path. |
||||
|
| permissions is an array with the permission flags for the directory (dir) |
||||
|
| and the create file (file). |
||||
|
| |
||||
|
*/ |
||||
|
'local_path' => storage_path('framework/cache/laravel-excel'), |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Local Temporary Path Permissions |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| Permissions is an array with the permission flags for the directory (dir) |
||||
|
| and the create file (file). |
||||
|
| If omitted the default permissions of the filesystem will be used. |
||||
|
| |
||||
|
*/ |
||||
|
'local_permissions' => [ |
||||
|
// 'dir' => 0755, |
||||
|
// 'file' => 0644, |
||||
|
], |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Remote Temporary Disk |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When dealing with a multi server setup with queues in which you |
||||
|
| cannot rely on having a shared local temporary path, you might |
||||
|
| want to store the temporary file on a shared disk. During the |
||||
|
| queue executing, we'll retrieve the temporary file from that |
||||
|
| location instead. When left to null, it will always use |
||||
|
| the local path. This setting only has effect when using |
||||
|
| in conjunction with queued imports and exports. |
||||
|
| |
||||
|
*/ |
||||
|
'remote_disk' => null, |
||||
|
'remote_prefix' => null, |
||||
|
|
||||
|
/* |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| Force Resync |
||||
|
|-------------------------------------------------------------------------- |
||||
|
| |
||||
|
| When dealing with a multi server setup as above, it's possible |
||||
|
| for the clean up that occurs after entire queue has been run to only |
||||
|
| cleanup the server that the last AfterImportJob runs on. The rest of the server |
||||
|
| would still have the local temporary file stored on it. In this case your |
||||
|
| local storage limits can be exceeded and future imports won't be processed. |
||||
|
| To mitigate this you can set this config value to be true, so that after every |
||||
|
| queued chunk is processed the local temporary file is deleted on the server that |
||||
|
| processed it. |
||||
|
| |
||||
|
*/ |
||||
|
'force_resync_remote' => null, |
||||
|
], |
||||
|
]; |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?php |
||||
|
return [ |
||||
|
'vip_list' => [ |
||||
|
'license' => '车牌号码', |
||||
|
'import_template' => 'VIP名单导入模板', |
||||
|
'list' => 'VIP名单' |
||||
|
] |
||||
|
]; |
||||
Loading…
Reference in new issue