歌手加入滙入功能
歌手新增修改頁補權限 20250505
This commit is contained in:
parent
d9924bf05b
commit
ac8a4f2eb0
47
app/Imports/ArtistDataImport.php
Normal file
47
app/Imports/ArtistDataImport.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Artist;
|
||||
use App\Enums\ArtistCategory;
|
||||
use Maatwebsite\Excel\Concerns\ToModel;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
use Maatwebsite\Excel\Imports\HeadingRowFormatter;
|
||||
|
||||
class ArtistDataImport implements ToModel, WithHeadingRow
|
||||
{
|
||||
public int $successCount = 0;
|
||||
public int $failCount = 0;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// 關閉 heading row 格式化
|
||||
HeadingRowFormatter::default('none');
|
||||
}
|
||||
|
||||
public function model(array $row)
|
||||
{
|
||||
$name = trim($row['名稱'] ?? '');
|
||||
$category = trim($row['類別'] ?? '未定義');
|
||||
if (empty($name)) {
|
||||
$this->failCount++;
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Artist::firstOrCreate(
|
||||
['name' => $name],
|
||||
['category' => ArtistCategory::tryFrom($category) ?? ArtistCategory::Unset]
|
||||
);
|
||||
$this->successCount++;
|
||||
} catch (\Throwable $e) {
|
||||
$this->failCount++;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public function headingRow(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -4,14 +4,19 @@ namespace App\Livewire\Admin;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\Artist;
|
||||
use App\Enums\ArtistCategory;
|
||||
|
||||
class ArtistForm extends Component
|
||||
{
|
||||
protected $listeners = ['openCreateArtistModal','openEditArtistModal', 'deleteArtist'];
|
||||
protected $listeners = ['openModal','closeModal', 'deleteArtist'];
|
||||
|
||||
public bool $showCreateModal = false;
|
||||
public bool $canCreate;
|
||||
public bool $canEdit;
|
||||
public bool $canDelect;
|
||||
|
||||
public bool $showModal = false;
|
||||
public ?int $artistId = null;
|
||||
|
||||
public array $categoryOptions =[];
|
||||
@ -29,43 +34,64 @@ class ArtistForm extends Component
|
||||
'name' => $category->labels(),
|
||||
'value' => $category->value,
|
||||
])->toArray();
|
||||
$this->canCreate = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canEdit = Auth::user()?->can('song-edit') ?? false;
|
||||
$this->canDelect = Auth::user()?->can('song-delete') ?? false;
|
||||
}
|
||||
|
||||
public function openCreateArtistModal()
|
||||
public function openModal($id = null)
|
||||
{
|
||||
$this->resetFields();
|
||||
$this->showCreateModal = true;
|
||||
|
||||
if ($id) {
|
||||
$artist = Artist::findOrFail($id);
|
||||
$this->artistId = $artist->id;
|
||||
$this->fields = $artist->only(array_keys($this->fields));
|
||||
}
|
||||
|
||||
$this->showModal = true;
|
||||
}
|
||||
|
||||
public function openEditArtistModal($id)
|
||||
public function closeModal()
|
||||
{
|
||||
$artist = Artist::findOrFail($id);
|
||||
$this->artistId = $artist->id;
|
||||
$this->fields = $artist->only(array_keys($this->fields));
|
||||
$this->showCreateModal = true;
|
||||
$this->resetFields();
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
|
||||
public function save()
|
||||
{
|
||||
|
||||
if ($this->artistId) {
|
||||
$artist = Artist::findOrFail($this->artistId);
|
||||
$artist->update($this->fields);
|
||||
session()->flash('message', '歌手已更新');
|
||||
if ($this->canEdit) {
|
||||
$artist = Artist::findOrFail($this->artistId);
|
||||
$artist->update($this->fields);
|
||||
$this->dispatch('notify', [
|
||||
'title' => '成功',
|
||||
'description' => '歌手已更新',
|
||||
'icon' => 'success',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$artist = Artist::create($this->fields);
|
||||
session()->flash('message', '歌手已新增');
|
||||
if ($canCreate) {
|
||||
$artist = Artist::create($this->fields);
|
||||
$this->dispatch('notify', [
|
||||
'title' => '成功',
|
||||
'description' => '歌手已新增',
|
||||
'icon' => 'success',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->resetFields();
|
||||
$this->showCreateModal = false;
|
||||
$this->showModal = false;
|
||||
$this->dispatch('pg:eventRefresh-artist-table');
|
||||
}
|
||||
|
||||
public function deleteArtist($id)
|
||||
{
|
||||
Artist::findOrFail($id)->delete();
|
||||
session()->flash('message', '歌手已刪除');
|
||||
if ($this->canDelect) {
|
||||
Artist::findOrFail($id)->delete();
|
||||
session()->flash('message', '歌手已刪除');
|
||||
$this->dispatch('pg:eventRefresh-artist-table');
|
||||
}
|
||||
}
|
||||
|
||||
public function resetFields()
|
||||
|
59
app/Livewire/Admin/ArtistImportData.php
Normal file
59
app/Livewire/Admin/ArtistImportData.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Admin;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Imports\ArtistDataImport;
|
||||
|
||||
class ArtistImportData extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
protected $listeners = ['openModal','closeModal'];
|
||||
|
||||
public bool $canCreate;
|
||||
|
||||
public bool $showModal = false;
|
||||
|
||||
public $file;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->canCreate = Auth::user()?->can('song-edit') ?? false;
|
||||
}
|
||||
|
||||
public function openModal()
|
||||
{
|
||||
$this->showModal = true;
|
||||
}
|
||||
public function closeModal()
|
||||
{
|
||||
$this->showModal = false;
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
// 檢查檔案是否有上傳
|
||||
$this->validate([
|
||||
'file' => 'required|file|mimes:csv,xlsx,xls'
|
||||
]);
|
||||
if ($this->canCreate) {
|
||||
$import = new ArtistDataImport();
|
||||
Excel::import($import, $this->file);
|
||||
$success = $import->successCount;
|
||||
$fail = $import->failCount;
|
||||
$this->reset('file');
|
||||
$this->showModal =false;
|
||||
session()->flash('message', '匯入完成:成功 $success 筆,失敗 $fail 筆。');
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.admin.artist-import-data');
|
||||
}
|
||||
|
||||
}
|
@ -193,7 +193,7 @@ final class ArtistTable extends PowerGridComponent
|
||||
->slot(__('artists.edit'))
|
||||
->icon('solid-pencil-square')
|
||||
->class('inline-flex items-center gap-1 px-3 py-1 rounded ')
|
||||
->dispatchTo('admin.artist-form', 'openEditArtistModal', ['id' => $row->id]);
|
||||
->dispatchTo('admin.artist-form', 'openModal', ['id' => $row->id]);
|
||||
}
|
||||
if($this->canDelect){
|
||||
$actions[] =Button::add('delete')
|
||||
|
380
config/excel.php
Normal file
380
config/excel.php
Normal file
@ -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,
|
||||
],
|
||||
];
|
@ -3,8 +3,9 @@
|
||||
return [
|
||||
'management' => '歌手管理',
|
||||
'list' => '歌手列表',
|
||||
'CreateNew' => '新增歌手',
|
||||
'CreateNew' => '新增',
|
||||
'EditArtist' => '編輯歌手',
|
||||
'ImportData' => '滙入',
|
||||
'create_edit' => '新增 / 編輯',
|
||||
'create' => '新增',
|
||||
'edit' => '編輯',
|
||||
|
@ -1,4 +1,4 @@
|
||||
<x-wireui:modal-card title="{{ $artistId ? __('artists.EditArtist') : __('artists.CreateNew') }}" blur wire:model.defer="showCreateModal">
|
||||
<x-wireui:modal-card title="{{ $artistId ? __('artists.EditArtist') : __('artists.CreateNew') }}" blur wire:model.defer="showModal">
|
||||
<div class="space-y-4">
|
||||
<x-wireui:select
|
||||
label="{{__('artists.category')}}"
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{__('artists.cancel')}}" @click="$wire.showCreateModal = false" />
|
||||
<x-wireui:button flat label="{{__('artists.cancel')}}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{__('artists.submit')}}" wire:click="save" />
|
||||
</div>
|
||||
</x-slot>
|
||||
|
@ -1,8 +1,15 @@
|
||||
<div class="flex justify-end mb-2">
|
||||
<div class="flex justify-end mb-2 mr-2 mt-2 sm:mt-0 gap-3">
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('admin.artist-form', 'openCreateArtistModal')"
|
||||
wire:click="$dispatchTo('admin.artist-form', 'openModal')"
|
||||
icon="plus"
|
||||
label="{{ __('artists.CreateNew') }}"
|
||||
class="bg-blue-600 text-white"
|
||||
/>
|
||||
|
||||
<x-wireui:button
|
||||
wire:click="$dispatchTo('admin.artist-import-data','openModal')"
|
||||
icon="document-plus"
|
||||
label="{{ __('artists.ImportData') }}"
|
||||
class="bg-green-600 text-white"
|
||||
/>
|
||||
</div>
|
43
resources/views/livewire/admin/artist-import-data.blade.php
Normal file
43
resources/views/livewire/admin/artist-import-data.blade.php
Normal file
@ -0,0 +1,43 @@
|
||||
<x-wireui:modal-card title="{{ __('artists.ImportData') }}" blur wire:model.defer="showModal">
|
||||
|
||||
{{-- 說明區塊 --}}
|
||||
<div class="mb-4 p-4 bg-gray-100 border border-gray-300 rounded text-sm text-gray-700">
|
||||
<p class="font-semibold mb-2">匯入格式說明</p>
|
||||
<p class="mb-2">請依下列表格格式準備 CSV 檔案:</p>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full text-sm text-left border border-collapse border-gray-300 mb-2">
|
||||
<thead class="bg-gray-200">
|
||||
<tr>
|
||||
<th class="border border-gray-300 px-3 py-1">類別</th>
|
||||
<th class="border border-gray-300 px-3 py-1">名稱</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="border border-gray-300 px-3 py-1">男</td>
|
||||
<td class="border border-gray-300 px-3 py-1">某男</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="border border-gray-300 px-3 py-1">女</td>
|
||||
<td class="border border-gray-300 px-3 py-1">某女</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-600 text-xs">
|
||||
※ 類別欄位僅可使用:<strong>男</strong>、<strong>女</strong>、<strong>團</strong>、<strong>外</strong>、<strong>其他</strong>。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{{-- 檔案上傳 --}}
|
||||
<input type="file" wire:model="file" accept=".csv, .xls, .xlsx" class="mb-4 w-full" />
|
||||
|
||||
<x-slot name="footer">
|
||||
<div class="flex justify-between w-full">
|
||||
<x-wireui:button flat label="{{ __('artists.cancel') }}" wire:click="closeModal" />
|
||||
<x-wireui:button primary label="{{ __('artists.submit') }}" wire:click="import" />
|
||||
</div>
|
||||
</x-slot>
|
||||
</x-wireui:modal-card>
|
@ -1,6 +1,6 @@
|
||||
|
||||
<x-layouts.admin>
|
||||
@if (session()->has('message'))
|
||||
|
||||
<x-wireui:notifications />
|
||||
<script>
|
||||
window.$wireui.notify({
|
||||
@ -9,11 +9,11 @@
|
||||
icon: 'success'
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
|
||||
{{-- 單一 Livewire 元件,內含資料表與 Modal --}}
|
||||
|
||||
|
||||
<livewire:admin.artist-table />
|
||||
<livewire:admin.artist-form />
|
||||
<livewire:admin.artist-import-data />
|
||||
</x-layouts.admin>
|
Loading…
x
Reference in New Issue
Block a user