Files
chatroom/app/Http/Controllers/Admin/ShopItemController.php
lkddi 759fb6deae 功能:后台新增商店管理页面(站长菜单)
- 路由: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 可新增/删除
2026-03-01 16:47:34 +08:00

114 lines
3.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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',
]);
}
}