功能:后台新增商店管理页面(站长菜单)

- 路由:GET/POST/PUT/PATCH/DELETE /admin/shop
- 控制器:Admin/ShopItemController(index/store/update/toggle/destroy)
- 视图:admin/shop/index.blade.php
  - 表格展示所有商品(名称/类型色标/价格/有效期/排序/状态)
  - Alpine.js 弹窗新增/编辑(支持全字段)
  - 上下架一键切换(PATCH toggle)
  - 删除按键(含二次确认)
- 侧边栏:VIP 下方新增「🛒 商店管理」链接
- 权限:superlevel 可查看/编辑;id=1 可新增/删除
This commit is contained in:
2026-03-01 16:47:34 +08:00
parent 0ea6ea206c
commit 759fb6deae
4 changed files with 475 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
<?php
/**
* 文件功能:后台商店商品管理控制器(站长功能)
*
* 提供商店商品的查看、编辑、切换上下架、删除等 CRUD 功能。
* superlevel 及以上可访问id=1 超级站长才能新增/删除。
*
* @author ChatRoom Laravel
*
* @version 1.0.0
*/
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\ShopItem;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
class ShopItemController extends Controller
{
/**
* 商品列表页(所有 superlevel 以上可查看)
*/
public function index(): View
{
$items = ShopItem::orderBy('sort_order')->orderBy('id')->get();
return view('admin.shop.index', compact('items'));
}
/**
* 新增商品(仅 id=1 超级站长)
*/
public function store(Request $request): RedirectResponse
{
abort_unless(Auth::id() === 1, 403);
$data = $this->validateItem($request);
ShopItem::create($data);
return redirect()->route('admin.shop.index')->with('success', '商品「'.$data['name'].'」创建成功!');
}
/**
* 更新商品信息
*
* @param ShopItem $shopItem 路由模型自动注入
*/
public function update(Request $request, ShopItem $shopItem): RedirectResponse
{
$data = $this->validateItem($request, $shopItem);
$shopItem->update($data);
return redirect()->route('admin.shop.index')->with('success', '商品「'.$shopItem->name.'」更新成功!');
}
/**
* 切换商品上下架状态
*
* @param ShopItem $shopItem 路由模型自动注入
*/
public function toggle(ShopItem $shopItem): RedirectResponse
{
$shopItem->update(['is_active' => ! $shopItem->is_active]);
$status = $shopItem->is_active ? '上架' : '下架';
return redirect()->route('admin.shop.index')->with('success', "{$shopItem->name}」已{$status}");
}
/**
* 删除商品(仅 id=1 超级站长)
*
* @param ShopItem $shopItem 路由模型自动注入
*/
public function destroy(ShopItem $shopItem): RedirectResponse
{
abort_unless(Auth::id() === 1, 403);
$name = $shopItem->name;
$shopItem->delete();
return redirect()->route('admin.shop.index')->with('success', "{$name}」已删除。");
}
/**
* 统一验证商品表单(新增/编辑共用)
*
* @return array<string, mixed>
*/
private function validateItem(Request $request, ?ShopItem $item = null): array
{
return $request->validate([
'name' => 'required|string|max:100',
'slug' => ['required', 'string', 'max:100',
\Illuminate\Validation\Rule::unique('shop_items', 'slug')->ignore($item?->id),
],
'icon' => 'required|string|max:20',
'description' => 'nullable|string|max:500',
'price' => 'required|integer|min:0',
'type' => 'required|in:instant,duration,one_time,ring,auto_fishing',
'duration_days' => 'nullable|integer|min:0',
'duration_minutes' => 'nullable|integer|min:0',
'intimacy_bonus' => 'nullable|integer|min:0',
'charm_bonus' => 'nullable|integer|min:0',
'sort_order' => 'required|integer|min:0',
'is_active' => 'boolean',
]);
}
}