后端管理
This commit is contained in:
@@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\admin\model\Admin;
|
||||||
|
use app\util\Util;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use support\Request;
|
||||||
|
use app\model\User;
|
||||||
|
use app\admin\model\Role;
|
||||||
|
|
||||||
|
class AdminController
|
||||||
|
{
|
||||||
|
public function list(Request $request,)
|
||||||
|
{
|
||||||
|
$page = $request->input('page', 1);
|
||||||
|
$perPage = $request->input('per_page', 10);
|
||||||
|
$admin = Admin::with('roles')->paginate($perPage, ['*'], 'page', $page);
|
||||||
|
return Util::success($admin);
|
||||||
|
}
|
||||||
|
// 获取用户角色列表
|
||||||
|
public function roles(Request $request, $id)
|
||||||
|
{
|
||||||
|
$admin = Admin::with('roles')->findOrFail($id);
|
||||||
|
$allRoles = Role::all();
|
||||||
|
|
||||||
|
$res = [
|
||||||
|
'admin' => $admin,
|
||||||
|
'all_roles' => $allRoles,
|
||||||
|
'assigned_roles' => $admin->roles->pluck('id')->toArray()
|
||||||
|
];
|
||||||
|
return Util::success($res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新用户角色
|
||||||
|
public function updateRoles(Request $request, $id)
|
||||||
|
{
|
||||||
|
// $request->validate([
|
||||||
|
// 'roles' => 'required|array',
|
||||||
|
// 'roles.*' => 'exists:roles,id'
|
||||||
|
// ]);
|
||||||
|
// 验证规则
|
||||||
|
$rules = [
|
||||||
|
'roles' => 'required|array',
|
||||||
|
'roles.*' => 'exists:roles,id'
|
||||||
|
];
|
||||||
|
|
||||||
|
// 自定义错误消息(可选)
|
||||||
|
$messages = [
|
||||||
|
'roles.required' => '角色不能为空',
|
||||||
|
'roles.exists' => '角色id不存在',
|
||||||
|
];
|
||||||
|
|
||||||
|
// 执行验证
|
||||||
|
$validator = Validator::make($request->all(), $rules, $messages);
|
||||||
|
|
||||||
|
$admin = Admin::findOrFail($id);
|
||||||
|
|
||||||
|
$res = $admin->roles()->sync($request->input('roles'));
|
||||||
|
|
||||||
|
return Util::success($res,'角色更新成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建管理员
|
||||||
|
public function create(Request $request)
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'username' => ['required', 'string', 'min:5', 'regex:/^[a-zA-Z0-9\-\_\.]+$/'],
|
||||||
|
'password' => 'required|string|min:6',
|
||||||
|
'nickname' => 'required|string',
|
||||||
|
'email' => 'nullable|email',
|
||||||
|
'status' => 'in:0,1'
|
||||||
|
];
|
||||||
|
|
||||||
|
$messages = [
|
||||||
|
'username.required' => '账号不能为空',
|
||||||
|
'username.min' => '账号长度不能少于5位',
|
||||||
|
'username.regex' => '账号只能包含字母、数字、下划线、连字符和点号',
|
||||||
|
'password.required' => '密码不能为空',
|
||||||
|
'password.min' => '密码长度不能少于6位',
|
||||||
|
'nickname.required' => '姓名不能为空',
|
||||||
|
'email.email' => '邮箱格式不正确',
|
||||||
|
'status.in' => '状态值不正确'
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($request->all(), $rules, $messages);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return Util::fail('',$validator->errors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查用户名是否已存在
|
||||||
|
if (Admin::where('username', $request->input('username'))->exists()) {
|
||||||
|
return Util::fail('','账号已存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查邮箱是否已存在
|
||||||
|
if ($request->input('email') && Admin::where('email', $request->input('email'))->exists()) {
|
||||||
|
return Util::fail('','邮箱已存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = new Admin();
|
||||||
|
$admin->username = $request->input('username');
|
||||||
|
$admin->password = password_hash($request->input('password'), PASSWORD_DEFAULT);
|
||||||
|
$admin->nickname = $request->input('nickname');
|
||||||
|
$admin->email = $request->input('email', null);
|
||||||
|
$admin->status = $request->input('status', 1);
|
||||||
|
$admin->save();
|
||||||
|
|
||||||
|
if ($request->input('roles')) {
|
||||||
|
$res = $admin->roles()->sync($request->input('roles'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Util::success($admin, '管理员创建成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改管理员信息
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$admin = Admin::findOrFail($id);
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
'password' => ['string', 'min:6', 'regex:/^[a-zA-Z0-9\-\_\.]+$/'],
|
||||||
|
'nickname' => 'string',
|
||||||
|
'email' => 'email',
|
||||||
|
'status' => 'in:0,1',
|
||||||
|
'old_password' => 'required_with:password|string',
|
||||||
|
'avatar' => 'string',
|
||||||
|
'mobile' => 'string'
|
||||||
|
];
|
||||||
|
|
||||||
|
$messages = [
|
||||||
|
'password.min' => '密码长度不能少于6位',
|
||||||
|
'password.regex' => '密码只能包含字母、数字、下划线、连字符和点号',
|
||||||
|
'email.email' => '邮箱格式不正确',
|
||||||
|
'status.in' => '状态值不正确',
|
||||||
|
'old_password.required_with' => '请提供旧密码',
|
||||||
|
'old_password.string' => '旧密码格式不正确'
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($request->all(), $rules, $messages);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return Util::fail('',$validator->errors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查邮箱是否已存在(排除当前管理员)
|
||||||
|
if ($request->input('email') && Admin::where('email', $request->input('email'))->where('id', '!=', $id)->exists()) {
|
||||||
|
return Util::fail('','邮箱已存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备要更新的数据
|
||||||
|
$updateData = $request->only(['nickname', 'email', 'status', 'avatar', 'mobile']);
|
||||||
|
|
||||||
|
// 如果修改密码,验证旧密码
|
||||||
|
if ($request->input('password')) {
|
||||||
|
if (!$request->input('old_password')) {
|
||||||
|
return Util::fail('','请提供旧密码');
|
||||||
|
}
|
||||||
|
if (!password_verify($request->input('old_password'), $admin->password)) {
|
||||||
|
return Util::fail('','旧密码不正确');
|
||||||
|
}
|
||||||
|
$updateData['password'] = password_hash($request->input('password'), PASSWORD_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只填充前端传递的字段
|
||||||
|
$admin->fill($updateData);
|
||||||
|
$admin->save();
|
||||||
|
|
||||||
|
return Util::success($admin, '管理员信息更新成功');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁用/启用管理员
|
||||||
|
public function toggleStatus(Request $request, $id)
|
||||||
|
{
|
||||||
|
$admin = Admin::findOrFail($id);
|
||||||
|
$admin->status = $admin->status == 1 ? 0 : 1;
|
||||||
|
$admin->save();
|
||||||
|
|
||||||
|
$statusText = $admin->status == 1 ? '启用' : '禁用';
|
||||||
|
return Util::success($admin, "管理员{$statusText}成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置管理员密码
|
||||||
|
public function resetPassword(Request $request, $id)
|
||||||
|
{
|
||||||
|
$rules = [
|
||||||
|
'new_password' => 'required|string|min:6',
|
||||||
|
// 'confirm_password' => 'required|string|same:new_password'
|
||||||
|
];
|
||||||
|
|
||||||
|
$messages = [
|
||||||
|
'new_password.required' => '新密码不能为空',
|
||||||
|
'new_password.min' => '新密码长度不能少于6位',
|
||||||
|
// 'confirm_password.required' => '确认密码不能为空',
|
||||||
|
// 'confirm_password.same' => '两次输入的密码不一致'
|
||||||
|
];
|
||||||
|
|
||||||
|
$validator = Validator::make($request->all(), $rules, $messages);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return Util::fail('',$validator->errors()->first());
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = Admin::findOrFail($id);
|
||||||
|
$admin->password = password_hash($request->input('new_password'), PASSWORD_DEFAULT);
|
||||||
|
$admin->save();
|
||||||
|
|
||||||
|
return Util::success(null, '密码重置成功');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\admin\model\Admin;
|
||||||
|
use app\admin\model\Menu;
|
||||||
|
use app\util\Util;
|
||||||
|
use support\Redis;
|
||||||
|
use support\Request;
|
||||||
|
use app\util\JwtUtil;
|
||||||
|
|
||||||
|
class AuthController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 不需要登录的方法
|
||||||
|
*/
|
||||||
|
protected $noNeedLogin = ['login'];
|
||||||
|
public function login(Request $request)
|
||||||
|
{
|
||||||
|
$username = Util::getParam($request, 'username');
|
||||||
|
if (Util::isEmpty($username)) {
|
||||||
|
return Util::fail([], trans('required_not_null'));
|
||||||
|
}
|
||||||
|
$password = Util::getParam($request, 'password');
|
||||||
|
if (Util::isEmpty($password)) {
|
||||||
|
return Util::fail([], trans('required_not_null'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = Admin::where('status', 1)
|
||||||
|
->where('username', $username)
|
||||||
|
->first();
|
||||||
|
if (!$admin) {
|
||||||
|
return Util::fail(['user' => $admin], trans('user_none'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$userPassword = $admin->password;
|
||||||
|
$user = $admin->toArray();
|
||||||
|
|
||||||
|
//加密
|
||||||
|
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
//验证密码
|
||||||
|
if (!password_verify($password, $userPassword)) {
|
||||||
|
return Util::fail([], trans('password_error'));
|
||||||
|
}
|
||||||
|
$userId = $user['id']; // 实际从数据库获取
|
||||||
|
|
||||||
|
|
||||||
|
Redis::set('admin_' . $userId, $user);
|
||||||
|
|
||||||
|
//密码验证成功后加密生成 Token
|
||||||
|
$token = JwtUtil::generateToken('admin_'.$userId);
|
||||||
|
$result = $user;
|
||||||
|
unset($result['password']);
|
||||||
|
$result['token'] = $token;
|
||||||
|
|
||||||
|
return Util::success($result, trans('login_success'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function menus(Request $request)
|
||||||
|
{
|
||||||
|
$user = $request->user;
|
||||||
|
$menus = Menu::with(['child.child' => function($query) {
|
||||||
|
$query->where('status', 1)->orderBy('sort');
|
||||||
|
}])
|
||||||
|
->where('parent_id', 0)
|
||||||
|
->where('status', 1)
|
||||||
|
->orderBy('sort')
|
||||||
|
->get()
|
||||||
|
->filter(function($menu) use ($user) {
|
||||||
|
if (empty($menu->permission_slug)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $user->hasPermission($menu->permission_slug);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Util::success($menus);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\model\Customer;
|
||||||
|
use app\model\User;
|
||||||
|
use app\util\Util;
|
||||||
|
use support\Request;
|
||||||
|
|
||||||
|
class CustomerController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 客户列表
|
||||||
|
* @param Request $request
|
||||||
|
* @return \support\Response
|
||||||
|
*/
|
||||||
|
public function list(Request $request)
|
||||||
|
{
|
||||||
|
$page = $request->input('page', 1);
|
||||||
|
$perPage = $request->input('per_page', 10);
|
||||||
|
$where = [];
|
||||||
|
$user_id = $request->input('user_id');
|
||||||
|
if(empty($user_id) || $user_id == 0){
|
||||||
|
$where[] = ['user_id', '=', $request->input('user_id')];
|
||||||
|
}
|
||||||
|
$user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page);
|
||||||
|
$user = $user->toArray();
|
||||||
|
foreach ($user['data'] as &$item) {
|
||||||
|
unset($item['password']);
|
||||||
|
}
|
||||||
|
return Util::success($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function follow(Request $request)
|
||||||
|
{
|
||||||
|
$page = $request->input('page', 1);
|
||||||
|
$perPage = $request->input('per_page', 10);
|
||||||
|
$where = [];
|
||||||
|
if($request->input('user_id')){
|
||||||
|
$where[] = ['user_id', '=', $request->input('user_id')];
|
||||||
|
}
|
||||||
|
$user = Customer::with('user')->where($where)->paginate($perPage, ['*'], 'page', $page);
|
||||||
|
$user = $user->toArray();
|
||||||
|
foreach ($user['data'] as &$item) {
|
||||||
|
unset($item['password']);
|
||||||
|
}
|
||||||
|
return Util::success($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,10 +4,29 @@ namespace app\admin\controller;
|
|||||||
|
|
||||||
use app\admin\model\Permission;
|
use app\admin\model\Permission;
|
||||||
use app\admin\model\Role;
|
use app\admin\model\Role;
|
||||||
|
use app\util\Util;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
use support\Request;
|
use support\Request;
|
||||||
|
|
||||||
class RoleController
|
class RoleController
|
||||||
{
|
{
|
||||||
|
public function all(Request $request,)
|
||||||
|
{
|
||||||
|
$admin = Role::with('permissions')->where([['status',1]])->get();
|
||||||
|
return Util::success($admin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 角色列表
|
||||||
|
*/
|
||||||
|
public function list(Request $request,)
|
||||||
|
{
|
||||||
|
$page = $request->input('page', 1);
|
||||||
|
$perPage = $request->input('per_page', 10);
|
||||||
|
$admin = Role::with('permissions')->paginate($perPage, ['*'], 'page', $page);
|
||||||
|
return Util::success($admin);
|
||||||
|
}
|
||||||
|
|
||||||
// 获取角色权限列表
|
// 获取角色权限列表
|
||||||
public function permissions(Request $request, $id)
|
public function permissions(Request $request, $id)
|
||||||
{
|
{
|
||||||
@@ -27,14 +46,24 @@ class RoleController
|
|||||||
// 更新角色权限
|
// 更新角色权限
|
||||||
public function updatePermissions(Request $request, $id)
|
public function updatePermissions(Request $request, $id)
|
||||||
{
|
{
|
||||||
$request->validate([
|
// 验证规则
|
||||||
|
$rules = [
|
||||||
'permissions' => 'required|array',
|
'permissions' => 'required|array',
|
||||||
'permissions.*' => 'exists:permissions,id'
|
'permissions.*' => 'exists:permissions,id'
|
||||||
]);
|
];
|
||||||
|
|
||||||
$role = Role::findOrFail($id);
|
// 自定义错误消息(可选)
|
||||||
|
$messages = [
|
||||||
|
'permissions.required' => '角色不能为空',
|
||||||
|
'permissions.exists' => '角色id不存在',
|
||||||
|
];
|
||||||
|
|
||||||
|
// 执行验证
|
||||||
|
$validator = Validator::make($request->all(), $rules, $messages);
|
||||||
|
|
||||||
|
$role = Role::with('permissions')->findOrFail($id);
|
||||||
$role->permissions()->sync($request->input('permissions'));
|
$role->permissions()->sync($request->input('permissions'));
|
||||||
|
|
||||||
return json(['code' => 0, 'msg' => '权限更新成功']);
|
return Util::success($role,'角色更新成功');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,39 +2,22 @@
|
|||||||
|
|
||||||
namespace app\admin\controller;
|
namespace app\admin\controller;
|
||||||
|
|
||||||
use support\Request;
|
|
||||||
use app\model\User;
|
use app\model\User;
|
||||||
use app\admin\model\Role;
|
use app\util\Util;
|
||||||
|
use support\Request;
|
||||||
|
|
||||||
class UserController
|
class UserController
|
||||||
{
|
{
|
||||||
// 获取用户角色列表
|
|
||||||
public function roles(Request $request, $id)
|
|
||||||
{
|
|
||||||
$user = User::with('roles')->findOrFail($id);
|
|
||||||
$allRoles = Role::all();
|
|
||||||
|
|
||||||
return json([
|
public function list(Request $request,)
|
||||||
'code' => 0,
|
{
|
||||||
'data' => [
|
$page = $request->input('page', 1);
|
||||||
'user' => $user,
|
$perPage = $request->input('per_page', 10);
|
||||||
'all_roles' => $allRoles,
|
$user = User::paginate($perPage, ['*'], 'page', $page);
|
||||||
'assigned_roles' => $user->roles->pluck('id')->toArray()
|
$user = $user->toArray();
|
||||||
]
|
foreach ($user['data'] as &$item) {
|
||||||
]);
|
unset($item['password']);
|
||||||
}
|
}
|
||||||
|
return Util::success($user);
|
||||||
// 更新用户角色
|
|
||||||
public function updateRoles(Request $request, $id)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'roles' => 'required|array',
|
|
||||||
'roles.*' => 'exists:roles,id'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$user = User::findOrFail($id);
|
|
||||||
$user->roles()->sync($request->input('roles'));
|
|
||||||
|
|
||||||
return json(['code' => 0, 'msg' => '角色更新成功']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
namespace app\admin\controller;
|
namespace app\admin\controller;
|
||||||
|
|
||||||
|
use app\admin\model\Menu;
|
||||||
|
use support\Request;
|
||||||
|
|
||||||
class menus
|
class menus
|
||||||
{
|
{
|
||||||
public function menus(Request $request)
|
public function menus(Request $request)
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\admin\middleware;
|
||||||
|
|
||||||
|
use Webman\MiddlewareInterface;
|
||||||
|
use Webman\Http\Response;
|
||||||
|
use Webman\Http\Request;
|
||||||
|
use Tymon\JWTAuth\Exceptions\JWTException;
|
||||||
|
|
||||||
|
class AuthMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
public function process(Request $request, callable $handler): Response
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$token = $this->getTokenFromRequest($request);
|
||||||
|
|
||||||
|
if (!$token) {
|
||||||
|
return $this->unauthorized('缺少访问令牌');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$user = auth('api')->setToken($token)->user()) {
|
||||||
|
return $this->unauthorized('用户不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将用户信息存入请求
|
||||||
|
$request->user = $user;
|
||||||
|
|
||||||
|
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
|
||||||
|
return $this->unauthorized('令牌已过期');
|
||||||
|
} catch (JWTException $e) {
|
||||||
|
return $this->unauthorized('令牌无效');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $handler($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getTokenFromRequest(Request $request)
|
||||||
|
{
|
||||||
|
$header = $request->header('Authorization', '');
|
||||||
|
if (preg_match('/Bearer\s+(\S+)/', $header, $matches)) {
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
return $request->input('token');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function unauthorized($msg)
|
||||||
|
{
|
||||||
|
return json(['code' => 401, 'msg' => $msg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
namespace app\admin\middleware;
|
namespace app\admin\middleware;
|
||||||
|
|
||||||
|
use app\util\Util;
|
||||||
|
use ReflectionClass;
|
||||||
use Webman\MiddlewareInterface;
|
use Webman\MiddlewareInterface;
|
||||||
use Webman\Http\Response;
|
use Webman\Http\Response;
|
||||||
use Webman\Http\Request;
|
use Webman\Http\Request;
|
||||||
@@ -10,21 +12,40 @@ class PermissionCheck implements MiddlewareInterface
|
|||||||
{
|
{
|
||||||
public function process(Request $request, callable $handler): Response
|
public function process(Request $request, callable $handler): Response
|
||||||
{
|
{
|
||||||
$user = $request->user();
|
$user = $request->user;
|
||||||
$route = $request->route;
|
// $route = $request->route;
|
||||||
|
$route = $request->path();
|
||||||
|
|
||||||
// 检查角色
|
// 通过反射获取控制器哪些方法不需要登录
|
||||||
$roles = $route->param('roles');
|
$controller = new ReflectionClass($request->controller);
|
||||||
if ($roles && !$user->roles()->whereIn('name', (array)$roles)->exists()) {
|
$noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];
|
||||||
return json(['code' => 403, 'msg' => '需要特定角色才能访问']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查权限
|
$isLogin = !in_array($request->action, $noNeedLogin);
|
||||||
$permission = $route->param('permission');
|
|
||||||
if ($permission && !$user->hasPermission($permission)) {
|
$permission = substr($route,7);
|
||||||
return json(['code' => 403, 'msg' => '无权访问']);
|
|
||||||
|
$is_auth = str_starts_with($permission, 'auth');
|
||||||
|
$permissions = $user?$user->permissions():true;
|
||||||
|
if($isLogin && $permission && (empty($permissions) && !$is_auth) && !$user->isPermission($permission)){
|
||||||
|
return Util::fail('','无权访问该资源',401);
|
||||||
}
|
}
|
||||||
|
// // 检查角色
|
||||||
|
// $requiredRoles = $request->route->param('roles', []);
|
||||||
|
// if (!empty($requiredRoles) && !$user->hasAnyRole($requiredRoles)) {
|
||||||
|
// return $this->forbidden('需要特定角色才能访问');
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 检查权限
|
||||||
|
// $requiredPermission = $route->param('permission');
|
||||||
|
// if ($requiredPermission && !$user->hasPermission($requiredPermission)) {
|
||||||
|
// return $this->forbidden('无权访问该资源');
|
||||||
|
// }
|
||||||
|
|
||||||
return $handler($request);
|
return $handler($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function forbidden($msg)
|
||||||
|
{
|
||||||
|
return json(['code' => 403, 'msg' => $msg]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\admin\model;
|
||||||
|
|
||||||
|
use support\Model;
|
||||||
|
class Admin extends Model
|
||||||
|
{
|
||||||
|
protected $table = 'admins';
|
||||||
|
protected $hidden = ['password'];
|
||||||
|
|
||||||
|
public function roles()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Role::class, 'admin_roles', 'user_id', 'role_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasRole($role)
|
||||||
|
{
|
||||||
|
return $this->roles()->where('name', $role)->exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getJWTIdentifier()
|
||||||
|
{
|
||||||
|
return $this->getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getJWTCustomClaims()
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAnyRole($roles)
|
||||||
|
{
|
||||||
|
return $this->roles()->whereIn('name', (array)$roles)->exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasPermission($permission)
|
||||||
|
{
|
||||||
|
return $this->permissions()->contains('slug', $permission);
|
||||||
|
}
|
||||||
|
public function isPermission($permission)
|
||||||
|
{
|
||||||
|
$permissions = $this->permissions();
|
||||||
|
return in_array($permission, array_column($permissions->toArray(), 'slug'));
|
||||||
|
}
|
||||||
|
public function permissions()
|
||||||
|
{
|
||||||
|
return $this->roles()
|
||||||
|
->with('permissions')
|
||||||
|
->get()
|
||||||
|
->pluck('permissions')
|
||||||
|
->flatten()
|
||||||
|
->unique('id');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ class Menu extends Model
|
|||||||
{
|
{
|
||||||
protected $table = 'menus';
|
protected $table = 'menus';
|
||||||
|
|
||||||
public function children()
|
public function child()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Menu::class, 'parent_id')->orderBy('sort');
|
return $this->hasMany(Menu::class, 'parent_id')->orderBy('sort');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class Role extends Model
|
|||||||
|
|
||||||
public function users()
|
public function users()
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(User::class, 'user_roles', 'role_id', 'user_id');
|
return $this->belongsToMany(Admin::class, 'user_roles', 'role_id', 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function permissions()
|
public function permissions()
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace app\admin\model;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
class User extends Model
|
|
||||||
{
|
|
||||||
protected $table = 'users';
|
|
||||||
protected $hidden = ['password'];
|
|
||||||
|
|
||||||
public function roles()
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(Role::class, 'user_roles', 'user_id', 'role_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasRole($role)
|
|
||||||
{
|
|
||||||
return $this->roles()->where('name', $role)->exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function hasPermission($permission)
|
|
||||||
{
|
|
||||||
return $this->roles()
|
|
||||||
->whereHas('permissions', function($query) use ($permission) {
|
|
||||||
$query->where('slug', $permission);
|
|
||||||
})
|
|
||||||
->exists();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
namespace app\middleware;
|
namespace app\middleware;
|
||||||
|
|
||||||
|
|
||||||
|
use app\admin\model\Admin;
|
||||||
use app\model\User;
|
use app\model\User;
|
||||||
use app\util\JwtUtil;
|
use app\util\JwtUtil;
|
||||||
use app\util\Util;
|
use app\util\Util;
|
||||||
@@ -77,17 +78,27 @@ class AuthMiddleware implements MiddlewareInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$userId = $decoded->sub;
|
$userId = $decoded->sub;
|
||||||
|
if(str_starts_with($userId,'admin_')){
|
||||||
|
$userId = substr($userId,6);
|
||||||
|
$user = Admin::find($userId);
|
||||||
|
if(!$user){
|
||||||
|
return Util::fail(['user'=>$user],trans('user_none'));
|
||||||
|
}
|
||||||
|
// $user = $user->toArray();
|
||||||
|
|
||||||
|
}else{
|
||||||
$user = User::select(['id','name','sex','role','avatar','email','password','language','created_at'])
|
$user = User::select(['id','name','sex','role','avatar','email','password','language','created_at'])
|
||||||
->find($userId);
|
->find($userId);
|
||||||
if(!$user){
|
if(!$user){
|
||||||
return Util::fail(['user'=>$user],trans('user_none'));
|
return Util::fail(['user'=>$user],trans('user_none'));
|
||||||
}
|
}
|
||||||
$user = $user->toArray();
|
$user = $user->toArray();
|
||||||
|
locale($user['language']);
|
||||||
|
}
|
||||||
|
|
||||||
// 将用户ID存入请求对象,供后续使用
|
// 将用户ID存入请求对象,供后续使用
|
||||||
// $request->user = ['id' => $userId];
|
// $request->user = ['id' => $userId];
|
||||||
$request->user = $user;
|
$request->user = $user;
|
||||||
locale($user['language']);
|
|
||||||
return $handler($request);
|
return $handler($request);
|
||||||
} catch (BusinessException $e) {
|
} catch (BusinessException $e) {
|
||||||
return json(['code' => 401, 'msg' => $e->getMessage()]);
|
return json(['code' => 401, 'msg' => $e->getMessage()]);
|
||||||
|
|||||||
@@ -128,4 +128,10 @@ class Customer extends Model
|
|||||||
{
|
{
|
||||||
return $this->hasMany(CustomerHis::class, 'customer_id', 'id');
|
return $this->hasMany(CustomerHis::class, 'customer_id', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义反向多对一关联
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -50,4 +50,10 @@ class User extends Model
|
|||||||
->toArray();
|
->toArray();
|
||||||
return $user;
|
return $user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义与 Customer 的一对多关系
|
||||||
|
public function customer()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Customer::class, 'user_id', 'id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -41,7 +41,9 @@
|
|||||||
"vlucas/phpdotenv": "^5.6",
|
"vlucas/phpdotenv": "^5.6",
|
||||||
"guzzlehttp/guzzle": "^7.9",
|
"guzzlehttp/guzzle": "^7.9",
|
||||||
"webman/cache": "^2.1",
|
"webman/cache": "^2.1",
|
||||||
"workerman/crontab": "^1.0"
|
"workerman/crontab": "^1.0",
|
||||||
|
"illuminate/validation": "^11.44",
|
||||||
|
"illuminate/container": "^11.44"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"ext-event": "For better performance. "
|
"ext-event": "For better performance. "
|
||||||
|
|||||||
Generated
+781
-2
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "a1bdf8bacc564776f13b4f4634c1b4c9",
|
"content-hash": "611cb43c328188aa7f01631e69f47567",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aliyuncs/oss-sdk-php",
|
"name": "aliyuncs/oss-sdk-php",
|
||||||
@@ -277,6 +277,162 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-18T20:23:39+00:00"
|
"time": "2024-02-18T20:23:39+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "doctrine/lexer",
|
||||||
|
"version": "3.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine/lexer.git",
|
||||||
|
"reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
|
||||||
|
"reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/coding-standard": "^12",
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpunit/phpunit": "^10.5",
|
||||||
|
"psalm/plugin-phpunit": "^0.18.3",
|
||||||
|
"vimeo/psalm": "^5.21"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Doctrine\\Common\\Lexer\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Guilherme Blanco",
|
||||||
|
"email": "guilhermeblanco@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Roman Borschel",
|
||||||
|
"email": "roman@code-factory.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Johannes Schmitt",
|
||||||
|
"email": "schmittjoh@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
|
||||||
|
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
|
||||||
|
"keywords": [
|
||||||
|
"annotations",
|
||||||
|
"docblock",
|
||||||
|
"lexer",
|
||||||
|
"parser",
|
||||||
|
"php"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/doctrine/lexer/issues",
|
||||||
|
"source": "https://github.com/doctrine/lexer/tree/3.0.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://www.patreon.com/phpdoctrine",
|
||||||
|
"type": "patreon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-02-05T11:56:58+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "egulias/email-validator",
|
||||||
|
"version": "4.0.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/egulias/EmailValidator.git",
|
||||||
|
"reference": "b115554301161fa21467629f1e1391c1936de517"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517",
|
||||||
|
"reference": "b115554301161fa21467629f1e1391c1936de517",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/lexer": "^2.0 || ^3.0",
|
||||||
|
"php": ">=8.1",
|
||||||
|
"symfony/polyfill-intl-idn": "^1.26"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^10.2",
|
||||||
|
"vimeo/psalm": "^5.12"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "4.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Egulias\\EmailValidator\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Eduardo Gulias Davis"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A library for validating emails against several RFCs",
|
||||||
|
"homepage": "https://github.com/egulias/EmailValidator",
|
||||||
|
"keywords": [
|
||||||
|
"email",
|
||||||
|
"emailvalidation",
|
||||||
|
"emailvalidator",
|
||||||
|
"validation",
|
||||||
|
"validator"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/egulias/EmailValidator/issues",
|
||||||
|
"source": "https://github.com/egulias/EmailValidator/tree/4.0.3"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/egulias",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-12-27T00:36:43+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "firebase/php-jwt",
|
"name": "firebase/php-jwt",
|
||||||
"version": "v6.11.0",
|
"version": "v6.11.0",
|
||||||
@@ -957,7 +1113,13 @@
|
|||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/illuminate/container/zipball/4dcc3fcbab92e734fc0c08d9cfd97f5a1aef18ca",
|
"url": "https://api.github.com/repos/illuminate/container/zipball/4dcc3fcbab92e734fc0c08d9cfd97f5a1aef18ca",
|
||||||
"reference": "4dcc3fcbab92e734fc0c08d9cfd97f5a1aef18ca",
|
"reference": "4dcc3fcbab92e734fc0c08d9cfd97f5a1aef18ca",
|
||||||
"shasum": ""
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/contracts": "^11.0",
|
"illuminate/contracts": "^11.0",
|
||||||
@@ -1168,6 +1330,79 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-01-31T17:44:22+00:00"
|
"time": "2025-01-31T17:44:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "illuminate/filesystem",
|
||||||
|
"version": "v11.44.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/illuminate/filesystem.git",
|
||||||
|
"reference": "c79a54ebc61ad4e1665ca7610f276ff8a92f48f7"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/illuminate/filesystem/zipball/c79a54ebc61ad4e1665ca7610f276ff8a92f48f7",
|
||||||
|
"reference": "c79a54ebc61ad4e1665ca7610f276ff8a92f48f7",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/collections": "^11.0",
|
||||||
|
"illuminate/contracts": "^11.0",
|
||||||
|
"illuminate/macroable": "^11.0",
|
||||||
|
"illuminate/support": "^11.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"symfony/finder": "^7.0.3"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-fileinfo": "Required to use the Filesystem class.",
|
||||||
|
"ext-ftp": "Required to use the Flysystem FTP driver.",
|
||||||
|
"ext-hash": "Required to use the Filesystem class.",
|
||||||
|
"illuminate/http": "Required for handling uploaded files (^7.0).",
|
||||||
|
"league/flysystem": "Required to use the Flysystem local driver (^3.25.1).",
|
||||||
|
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).",
|
||||||
|
"league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).",
|
||||||
|
"league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).",
|
||||||
|
"psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).",
|
||||||
|
"symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).",
|
||||||
|
"symfony/mime": "Required to enable support for guessing extensions (^7.0)."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "11.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"functions.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Illuminate\\Filesystem\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Otwell",
|
||||||
|
"email": "taylor@laravel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The Illuminate Filesystem package.",
|
||||||
|
"homepage": "https://laravel.com",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravel/framework/issues",
|
||||||
|
"source": "https://github.com/laravel/framework"
|
||||||
|
},
|
||||||
|
"time": "2025-02-19T20:17:00+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "illuminate/macroable",
|
"name": "illuminate/macroable",
|
||||||
"version": "v11.44.2",
|
"version": "v11.44.2",
|
||||||
@@ -1443,6 +1678,130 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-02-23T14:20:22+00:00"
|
"time": "2025-02-23T14:20:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "illuminate/translation",
|
||||||
|
"version": "v11.44.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/illuminate/translation.git",
|
||||||
|
"reference": "de64584470b1d4bfc30f2c291585b873ce844ecf"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/illuminate/translation/zipball/de64584470b1d4bfc30f2c291585b873ce844ecf",
|
||||||
|
"reference": "de64584470b1d4bfc30f2c291585b873ce844ecf",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/collections": "^11.0",
|
||||||
|
"illuminate/contracts": "^11.0",
|
||||||
|
"illuminate/filesystem": "^11.0",
|
||||||
|
"illuminate/macroable": "^11.0",
|
||||||
|
"illuminate/support": "^11.0",
|
||||||
|
"php": "^8.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "11.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Illuminate\\Translation\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Otwell",
|
||||||
|
"email": "taylor@laravel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The Illuminate Translation package.",
|
||||||
|
"homepage": "https://laravel.com",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravel/framework/issues",
|
||||||
|
"source": "https://github.com/laravel/framework"
|
||||||
|
},
|
||||||
|
"time": "2025-02-14T15:47:05+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "illuminate/validation",
|
||||||
|
"version": "v11.44.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/illuminate/validation.git",
|
||||||
|
"reference": "0abcf721a46d3c2a94f225dce82f3c00070f6121"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/illuminate/validation/zipball/0abcf721a46d3c2a94f225dce82f3c00070f6121",
|
||||||
|
"reference": "0abcf721a46d3c2a94f225dce82f3c00070f6121",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"brick/math": "^0.9.3|^0.10.2|^0.11|^0.12",
|
||||||
|
"egulias/email-validator": "^3.2.5|^4.0",
|
||||||
|
"ext-filter": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"illuminate/collections": "^11.0",
|
||||||
|
"illuminate/container": "^11.0",
|
||||||
|
"illuminate/contracts": "^11.0",
|
||||||
|
"illuminate/macroable": "^11.0",
|
||||||
|
"illuminate/support": "^11.0",
|
||||||
|
"illuminate/translation": "^11.0",
|
||||||
|
"php": "^8.2",
|
||||||
|
"symfony/http-foundation": "^7.0",
|
||||||
|
"symfony/mime": "^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"illuminate/database": "Required to use the database presence verifier (^11.0)."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "11.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Illuminate\\Validation\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Taylor Otwell",
|
||||||
|
"email": "taylor@laravel.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "The Illuminate Validation package.",
|
||||||
|
"homepage": "https://laravel.com",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/laravel/framework/issues",
|
||||||
|
"source": "https://github.com/laravel/framework"
|
||||||
|
},
|
||||||
|
"time": "2025-03-11T08:51:12+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/serializable-closure",
|
"name": "laravel/serializable-closure",
|
||||||
"version": "v2.0.3",
|
"version": "v2.0.3",
|
||||||
@@ -2953,6 +3312,250 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-09-25T14:20:29+00:00"
|
"time": "2024-09-25T14:20:29+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/finder",
|
||||||
|
"version": "v7.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/finder.git",
|
||||||
|
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/finder/zipball/6de263e5868b9a137602dd1e33e4d48bfae99c49",
|
||||||
|
"reference": "6de263e5868b9a137602dd1e33e4d48bfae99c49",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/filesystem": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Finder\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Finds files and directories via an intuitive fluent interface",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/finder/tree/v7.2.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-10-23T06:56:12+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/http-foundation",
|
||||||
|
"version": "v7.2.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/http-foundation.git",
|
||||||
|
"reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/62d1a43796ca3fea3f83a8470dfe63a4af3bc588",
|
||||||
|
"reference": "62d1a43796ca3fea3f83a8470dfe63a4af3bc588",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/deprecation-contracts": "^2.5|^3.0",
|
||||||
|
"symfony/polyfill-mbstring": "~1.1",
|
||||||
|
"symfony/polyfill-php83": "^1.27"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"doctrine/dbal": "<3.6",
|
||||||
|
"symfony/cache": "<6.4.12|>=7.0,<7.1.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"doctrine/dbal": "^3.6|^4",
|
||||||
|
"predis/predis": "^1.1|^2.0",
|
||||||
|
"symfony/cache": "^6.4.12|^7.1.5",
|
||||||
|
"symfony/dependency-injection": "^6.4|^7.0",
|
||||||
|
"symfony/expression-language": "^6.4|^7.0",
|
||||||
|
"symfony/http-kernel": "^6.4|^7.0",
|
||||||
|
"symfony/mime": "^6.4|^7.0",
|
||||||
|
"symfony/rate-limiter": "^6.4|^7.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\HttpFoundation\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/http-foundation/tree/v7.2.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-12-30T19:00:17+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/mime",
|
||||||
|
"version": "v7.2.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/mime.git",
|
||||||
|
"reference": "2fc3b4bd67e4747e45195bc4c98bea4628476204"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/mime/zipball/2fc3b4bd67e4747e45195bc4c98bea4628476204",
|
||||||
|
"reference": "2fc3b4bd67e4747e45195bc4c98bea4628476204",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/polyfill-intl-idn": "^1.10",
|
||||||
|
"symfony/polyfill-mbstring": "^1.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"egulias/email-validator": "~3.0.0",
|
||||||
|
"phpdocumentor/reflection-docblock": "<3.2.2",
|
||||||
|
"phpdocumentor/type-resolver": "<1.4.0",
|
||||||
|
"symfony/mailer": "<6.4",
|
||||||
|
"symfony/serializer": "<6.4.3|>7.0,<7.0.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"egulias/email-validator": "^2.1.10|^3.1|^4",
|
||||||
|
"league/html-to-markdown": "^5.0",
|
||||||
|
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
|
||||||
|
"symfony/dependency-injection": "^6.4|^7.0",
|
||||||
|
"symfony/process": "^6.4|^7.0",
|
||||||
|
"symfony/property-access": "^6.4|^7.0",
|
||||||
|
"symfony/property-info": "^6.4|^7.0",
|
||||||
|
"symfony/serializer": "^6.4.3|^7.0.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Mime\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Allows manipulating MIME messages",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"mime",
|
||||||
|
"mime-type"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/mime/tree/v7.2.3"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-01-27T11:08:17+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.31.0",
|
"version": "v1.31.0",
|
||||||
@@ -3038,6 +3641,182 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-09-09T11:45:10+00:00"
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-intl-idn",
|
||||||
|
"version": "v1.31.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||||
|
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
|
||||||
|
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2",
|
||||||
|
"symfony/polyfill-intl-normalizer": "^1.10"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Intl\\Idn\\": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Laurent Bassin",
|
||||||
|
"email": "laurent@bassin.info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Trevor Rowbotham",
|
||||||
|
"email": "trevor.rowbotham@pm.me"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"idn",
|
||||||
|
"intl",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
|
"version": "v1.31.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
|
"reference": "3833d7255cc303546435cb650316bff708a1c75c"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
|
||||||
|
"reference": "3833d7255cc303546435cb650316bff708a1c75c",
|
||||||
|
"shasum": "",
|
||||||
|
"mirrors": [
|
||||||
|
{
|
||||||
|
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
|
||||||
|
"preferred": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "For best performance"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"name": "symfony/polyfill",
|
||||||
|
"url": "https://github.com/symfony/polyfill"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Polyfill\\Intl\\Normalizer\\": ""
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"Resources/stubs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nicolas Grekas",
|
||||||
|
"email": "p@tchwork.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Symfony polyfill for intl's Normalizer class and related functions",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"compatibility",
|
||||||
|
"intl",
|
||||||
|
"normalizer",
|
||||||
|
"polyfill",
|
||||||
|
"portable",
|
||||||
|
"shim"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2024-09-09T11:45:10+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.31.0",
|
"version": "v1.31.0",
|
||||||
|
|||||||
@@ -12,6 +12,24 @@
|
|||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// 初始化 Laravel 容器
|
||||||
|
use Illuminate\Container\Container;
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
|
$container = Container::getInstance();
|
||||||
|
|
||||||
|
// 将容器设置为 Facade 的根
|
||||||
|
Facade::setFacadeApplication($container);
|
||||||
|
|
||||||
|
// 注册验证器服务(关键步骤)
|
||||||
|
$container->singleton('validator', function () {
|
||||||
|
return new \Illuminate\Validation\Factory(
|
||||||
|
new \Illuminate\Translation\Translator(
|
||||||
|
new \Illuminate\Translation\ArrayLoader(), 'en' // 默认语言
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
support\bootstrap\Session::class,
|
support\bootstrap\Session::class,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -17,5 +17,6 @@ return [
|
|||||||
'' => [
|
'' => [
|
||||||
app\middleware\CrossDomain::class, // 全局跨域中间件
|
app\middleware\CrossDomain::class, // 全局跨域中间件
|
||||||
app\middleware\AuthMiddleware::class, // 鉴权中间件
|
app\middleware\AuthMiddleware::class, // 鉴权中间件
|
||||||
|
app\admin\middleware\PermissionCheck::class, // 后端权限
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
Reference in New Issue
Block a user