后端管理
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\Role;
|
||||
use app\util\Util;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use support\Request;
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -27,14 +46,24 @@ class RoleController
|
||||
// 更新角色权限
|
||||
public function updatePermissions(Request $request, $id)
|
||||
{
|
||||
$request->validate([
|
||||
// 验证规则
|
||||
$rules = [
|
||||
'permissions' => 'required|array',
|
||||
'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'));
|
||||
|
||||
return json(['code' => 0, 'msg' => '权限更新成功']);
|
||||
return Util::success($role,'角色更新成功');
|
||||
}
|
||||
}
|
||||
@@ -2,39 +2,22 @@
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use support\Request;
|
||||
use app\model\User;
|
||||
use app\admin\model\Role;
|
||||
use app\util\Util;
|
||||
use support\Request;
|
||||
|
||||
class UserController
|
||||
{
|
||||
// 获取用户角色列表
|
||||
public function roles(Request $request, $id)
|
||||
|
||||
public function list(Request $request,)
|
||||
{
|
||||
$user = User::with('roles')->findOrFail($id);
|
||||
$allRoles = Role::all();
|
||||
|
||||
return json([
|
||||
'code' => 0,
|
||||
'data' => [
|
||||
'user' => $user,
|
||||
'all_roles' => $allRoles,
|
||||
'assigned_roles' => $user->roles->pluck('id')->toArray()
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// 更新用户角色
|
||||
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' => '角色更新成功']);
|
||||
$page = $request->input('page', 1);
|
||||
$perPage = $request->input('per_page', 10);
|
||||
$user = User::paginate($perPage, ['*'], 'page', $page);
|
||||
$user = $user->toArray();
|
||||
foreach ($user['data'] as &$item) {
|
||||
unset($item['password']);
|
||||
}
|
||||
return Util::success($user);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\Menu;
|
||||
use support\Request;
|
||||
|
||||
class menus
|
||||
{
|
||||
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;
|
||||
|
||||
use app\util\Util;
|
||||
use ReflectionClass;
|
||||
use Webman\MiddlewareInterface;
|
||||
use Webman\Http\Response;
|
||||
use Webman\Http\Request;
|
||||
@@ -10,21 +12,40 @@ class PermissionCheck implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
$user = $request->user();
|
||||
$route = $request->route;
|
||||
$user = $request->user;
|
||||
// $route = $request->route;
|
||||
$route = $request->path();
|
||||
|
||||
// 检查角色
|
||||
$roles = $route->param('roles');
|
||||
if ($roles && !$user->roles()->whereIn('name', (array)$roles)->exists()) {
|
||||
return json(['code' => 403, 'msg' => '需要特定角色才能访问']);
|
||||
}
|
||||
// 通过反射获取控制器哪些方法不需要登录
|
||||
$controller = new ReflectionClass($request->controller);
|
||||
$noNeedLogin = $controller->getDefaultProperties()['noNeedLogin'] ?? [];
|
||||
|
||||
// 检查权限
|
||||
$permission = $route->param('permission');
|
||||
if ($permission && !$user->hasPermission($permission)) {
|
||||
return json(['code' => 403, 'msg' => '无权访问']);
|
||||
$isLogin = !in_array($request->action, $noNeedLogin);
|
||||
|
||||
$permission = substr($route,7);
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
public function children()
|
||||
public function child()
|
||||
{
|
||||
return $this->hasMany(Menu::class, 'parent_id')->orderBy('sort');
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ class Role extends Model
|
||||
|
||||
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()
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user