角色管理

This commit is contained in:
zhang zhuo 2025-06-24 18:06:27 +08:00
parent d6f7f1cbf0
commit e5c4dd50b4
13 changed files with 445 additions and 63 deletions

View File

@ -18,6 +18,10 @@ use Hyperf\HttpServer\Annotation\PutMapping;
use App\Request\Menu as mRequest;
use App\Request\Role as rRequest;
use App\Request\Dept as dRequest;
use App\Model\Post as pModel;
use App\Request\Post as pRequest;
use App\Model\Account as aModel;
use App\Request\Account as aRequest;
#[Controller(prefix: "admin")]
class System extends Base
@ -84,35 +88,30 @@ class System extends Base
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[GetMapping(path: "dept/index")]
#[Auth(auth: "dept:index")]
public function deptIndex(): ResponseInterface
#[GetMapping(path: "dept/list")]
#[Auth(auth: "dept:list")]
public function deptList()
{
// 获取当前账号归属
$account = $this->request->getAttribute("account");
$dept_name = $this->request->input("dept_name", "");
return $this->success("菜单列表", Dept::depts($account['belong_id'], $account['account_type'], $dept_name));
return $this->success("菜单列表", dModel::list($this->account['belong_id'], $this->account['account_type'], $dept_name));
}
#[GetMapping(path: "dept/option")]
#[Auth(needAuth: false)]
public function deptOption(): ResponseInterface
public function deptOption()
{
// 获取当前账号归属
$account = $this->request->getAttribute("account");
return $this->success("菜单列表", Dept::options($account['belong_id'], $account['account_type']));
return $this->success("菜单列表", dModel::options($this->account['belong_id'], $this->account['account_type']));
}
#[PostMapping(path: "dept/add")]
#[Auth(auth: "dept:add")]
public function deptAdd()
{
$request = $this->container->get(DeptRequest::class);
$request = $this->container->get(dRequest::class);
$request->scene('add')->validateResolved();
$data = Com::only(['dept_name' => '', 'parent_id' => 0, 'rank', 'remark', 'status' => 1], $this->request->post());
$account = $this->request->getAttribute("account");
$data['belong_id'] = $account['belong_id'];
$data['belong'] = $account['account_type'];
$data = Param::only(['dept_name' => '', 'pid' => 0, 'rank', 'status' => 1]);
$data['belong_id'] = $this->account['belong_id'];
$data['account_type'] = $this->account['account_type'];
$res = dModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
@ -121,9 +120,9 @@ class System extends Base
#[Auth(auth: "dept:edit")]
public function deptEdit()
{
$request = $this->container->get(DeptRequest::class);
$request = $this->container->get(dRequest::class);
$request->scene('edit')->validateResolved();
$data = Com::only(['dept_id' => '', 'dept_name' => '', 'parent_id' => 0, 'rank', 'remark', 'status' => 1], $this->request->post());
$data = Param::only(['dept_id' => '', 'dept_name' => '', 'pid' => 0, 'rank', 'status' => 1]);
$res = dModel::edit($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
@ -191,4 +190,110 @@ class System extends Base
$res = rModel::del($ids);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[GetMapping(path: "post/list")]
#[Auth(auth: "post:list")]
public function postList()
{
$post_name = $this->request->input("post_name", "");
return $this->success("岗位列表", pModel::list($this->account['belong_id'], $this->account['account_type'], $post_name));
}
#[GetMapping(path: "post/option")]
#[Auth(needAuth: false)]
public function postOption()
{
return $this->success("岗位列表", pModel::options($this->account['belong_id'], $this->account['account_type']));
}
#[PostMapping(path: "post/add")]
#[Auth(auth: "post:add")]
public function postAdd()
{
$request = $this->container->get(pRequest::class);
$request->scene('add')->validateResolved();
$data = Param::only(['post_name' => '', 'rank', 'status' => 1]);
$data['belong_id'] = $this->account['belong_id'];
$data['account_type'] = $this->account['account_type'];
$res = pModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[PutMapping(path: "post/edit")]
#[Auth(auth: "post:edit")]
public function postEdit()
{
$request = $this->container->get(pRequest::class);
$request->scene('edit')->validateResolved();
$data = Param::only(['post_id' => '', 'post_name' => '', 'rank', 'status' => 1]);
$res = pModel::edit($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[DeleteMapping(path: "post/del")]
#[Auth(auth: "post:del")]
public function postDel()
{
$ids = $this->request->input("ids", "");
if (!$ids) return $this->error("请选择要删除的岗位");
$res = pModel::del($ids);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
// 账号列表
#[GetMapping(path: "account/list")]
#[Auth(auth: "account:list")]
public function accountList()
{
$where = Param::only(['username' => '', 'limit' => 1, 'dept_id' => '']);
$account = $this->request->getAttribute("account");
$rows = aModel::list($where, $account['belong_id'], $account['account_type']);
return $this->success("账户列表", $rows['data'], $rows['count']);
}
// 添加账号
#[PostMapping(path: "account/add")]
#[Auth(auth: "account:add")]
public function accountAdd()
{
$request = $this->container->get(aRequest::class);
$request->scene('add')->validateResolved();
$account = $this->request->getAttribute("account");
$data = Param::only(['roles' => [], 'username', 'status' => 1, 'dept_id' => 0, 'posts' => [], 'password' => '123456']);
// 判断数据库是否存在相同的用户名
$admin = aModel::getByUsername($data['username'], ['account_id']);
if (!empty($admin)) {
return $this->error('用户名已存在!');
}
$data['belong_id'] = $account['belong_id'];
$data['account_type'] = $account['account_type'];
$res = aModel::add($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
// 修改账号
#[PutMapping(path: "account/edit")]
#[Auth(auth: "account:edit")]
public function accountEdit()
{
$request = $this->container->get(aRequest::class);
$request->scene('edit')->validateResolved();
$data = Param::only(['roles' => [], 'username', 'status' => 1, 'dept_id' => 0, 'posts' => [], 'password' => '', 'account_id']);
$res = aModel::edit($data);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
// 删除账号
#[DeleteMapping(path: "account/del")]
#[Auth(auth: "account:del")]
public function accountDel()
{
$id = $this->request->input("ids");
if (!$id) return $this->error("请选择要删除的账号");
$account = aModel::getById($id, ['master_flag']);
if ($account['master_flag'] == 1) return $this->error("系统创建的主账号不允许删除");
if ($account['account_id'] == $id) return $this->error("不能删除自己的账号");
$res = aModel::del($id);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace App\Exception\Handler;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Hyperf\Validation\ValidationException;
use Psr\Http\Message\ResponseInterface;
use Throwable;
/**
* 自定义验证器输出
*/
class ValidationExceptionHandler extends ExceptionHandler
{
/**
* handle.
* @param Throwable $throwable
* @param ResponseInterface $response
* @return ResponseInterface
*/
public function handle(Throwable $throwable, ResponseInterface $response)
{
$this->stopPropagation();
/** @var \Hyperf\Validation\ValidationException $throwable */
$keys = $throwable->validator->errors()->keys();
if (count($keys) > 0) {
$msg = $keys[0] . str_replace("validation", "", $throwable->validator->errors()->first($keys[0]));
} else {
$msg = $throwable->validator->errors()->first();
}
if (!$response->hasHeader('content-type')) {
$response = $response->withAddedHeader('content-type', 'application/json; charset=utf-8');
}
return $response->withStatus(200)->withBody(new SwooleStream(json_encode(['code'=>1,'msg'=>$msg])));
}
/**
* 验证之后
* @param Throwable $throwable
* @return bool
*/
public function isValid(Throwable $throwable): bool
{
return $throwable instanceof ValidationException;
}
}

View File

@ -4,6 +4,9 @@ declare(strict_types=1);
namespace App\Model;
use App\Utils\Str;
use Hyperf\DbConnection\Db;
/**
* @property int $account_id
* @property int $account_type
@ -63,14 +66,6 @@ class Account extends Model
return $info->toArray();
}
public static function getById(int $account_id, array $field = ['*']): array
{
$info = self::where("account_id", $account_id)
->select($field)
->first();
return $info->toArray();
}
public static function getMenu(array $account)
{
// 总后台账号
@ -96,6 +91,134 @@ class Account extends Model
return compact("menus", "buttons", "roles");
}
public static function list(array $where, int $belong_id, int $account_type)
{
$model = self::where('belong_id', $belong_id)
->where('account_type', $account_type);
if ($where['username'] != '') {
$model = $model->where('username', "like", "%$where[username]%");
}
if ($where['dept_id'] != '') {
$model = $model->where('dept_id', $where['dept_id']);
}
$paginate = $model->orderByDesc("account_id")
->paginate((int)$where['limit'], ['account_id', 'username', 'avatar', 'create_time', 'dept_id']);
$count = $paginate->total();
$data = $paginate->items();
foreach ($data as &$item) {
$item['roles'] = AccountRole::getRole($item['account_id']);
$item['posts'] = AccountPost::getPost($item['account_id']);
}
return compact("data", "count");
}
/**
* 添加
* @param array $data
* @return bool
*/
public static function add(array $data)
{
$data['create_time'] = date("Y-m-d H:i:s");
$data['salt'] = Str::randStr(6);
$data['password'] = md5($data['salt'] . $data['password']);
$roles = $data['roles'];
$posts = $data['posts'];
unset($data['roles'], $data['posts']);
Db::beginTransaction();
$account_id = self::insertGetId($data);
if (!$account_id) {
Db::rollBack();
return false;
}
$account_role = [];
foreach ($roles as $role_id) {
$account_role[] = ['role_id' => $role_id, 'account_id' => $account_id];
}
if (!empty($account_role)) {
$res = AccountRole::insert($account_role);
if (!$res) {
Db::rollBack();
return false;
}
}
$account_post = [];
foreach ($posts as $post_id) {
$account_post[] = ['post_id' => $post_id, 'account_id' => $account_id];
}
if (!empty($account_post)) {
$res = AccountPost::insert($account_post);
if (!$res) {
Db::rollBack();
return false;
}
}
Db::commit();
return true;
}
/**
* 修改
* @param array $data
* @return bool
*/
public static function edit(array $data)
{
$data['update_time'] = date("Y-m-d H:i:s");
if ($data['password']) {
$data['salt'] = Str::randStr(6);
$data['password'] = md5($data['salt'] . $data['password']);
}else{
unset($data['password']);
unset($data['salt']);
}
$roles = $data['roles'];
$posts = $data['posts'];
unset($data['roles'], $data['posts']);
Db::beginTransaction();
$res = self::where("account_id", $data['account_id'])->update($data);
if (!$res) {
Db::rollBack();
return false;
}
// 删除之前的
$res1 = AccountRole::where('account_id', $data['account_id'])->delete();
if (!$res1) {
Db::rollBack();
return false;
}
$account_role = [];
foreach ($roles as $role_id) {
$account_role[] = ['role_id' => $role_id, 'account_id' => $data['account_id']];
}
// 重新添加
if (!empty($account_role)) {
if (!AccountRole::insert($account_role)) {
Db::rollBack();
return false;
}
}
// 删除之前的
$res1 = AccountPost::where('account_id', $data['account_id'])->delete();
if (!$res1) {
Db::rollBack();
return false;
}
$account_post = [];
foreach ($posts as $post_id) {
$account_post[] = ['post_id' => $post_id, 'account_id' => $data['account_id']];
}
// 重新添加
if (!empty($account_post)) {
if (!AccountPost::insert($account_post)) {
Db::rollBack();
return false;
}
}
Db::commit();
return true;
}
public function roles()
{
return $this->belongsToMany(

View File

@ -4,11 +4,13 @@ declare(strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* @property int $account_id
* @property int $post_id
*/
class AccountPost extends Model
class AccountPost extends \Hyperf\Database\Model\Model
{
/**
* The table associated with the model.
@ -24,4 +26,12 @@ class AccountPost extends Model
* The attributes that should be cast to native types.
*/
protected array $casts = ['account_id' => 'integer', 'post_id' => 'integer'];
public static function getPost(int $account_id)
{
return Db::table("account_post")
->leftJoin('post', 'post.post_id', '=', 'account_post.post_id')
->where('account_post.account_id', $account_id)
->select(["post.post_id","post.post_name"])->get()->toArray();
}
}

View File

@ -4,11 +4,13 @@ declare(strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* @property int $account_id
* @property int $role_id
*/
class AccountRole extends Model
class AccountRole extends \Hyperf\Database\Model\Model
{
/**
* The table associated with the model.
@ -24,4 +26,12 @@ class AccountRole extends Model
* The attributes that should be cast to native types.
*/
protected array $casts = ['account_id' => 'integer', 'role_id' => 'integer'];
public static function getRole(int $account_id)
{
return Db::table("account_role")
->leftJoin('role', 'role.role_id', '=', 'account_role.role_id')
->where('account_role.account_id', $account_id)
->select(["role.role_id","role.role_name"])->get()->toArray();
}
}

View File

@ -1,6 +1,7 @@
<?php
declare (strict_types=1);
namespace App\Model;
/**
@ -40,4 +41,26 @@ class Dept extends Model
*/
protected array $casts = ['dept_id' => 'integer', 'pid' => 'integer', 'belong_id' => 'integer', 'account_type' => 'integer', 'status' => 'integer', 'rank' => 'integer', 'del_flag' => 'integer'];
public static function list(int $belong_id, int $account_type, string $dept_name)
{
$model = self::where('belong_id', $belong_id)
->where('account_type', $account_type);
if ($dept_name != '') {
$model = $model->where('dept_name', "like", "%$dept_name%");
}
return $model->orderByDesc("rank")
->select(["dept_id", "pid", "dept_name", "rank", "status", "create_time"])
->get()->toArray();
}
public static function options(int $belong_id, int $account_type)
{
return self::where('belong_id', $belong_id)
->where('account_type', $account_type)
->where("status",1)
->orderByDesc("rank")
->select(["dept_id", "pid", "dept_name"])
->get()->toArray();
}
}

View File

@ -8,7 +8,9 @@ namespace App\Model;
* @property int $post_id
* @property int $account_type
* @property int $belong_id
* @property string $post_name
* @property string $post_name
* @property int $status
* @property int $rank
* @property string $create_time
* @property string $update_time
* @property string $deleted_at
@ -30,5 +32,27 @@ class Post extends Model
/**
* The attributes that should be cast to native types.
*/
protected array $casts = ['post_id' => 'integer', 'account_type' => 'integer', 'belong_id' => 'integer'];
protected array $casts = ['post_id' => 'integer', 'account_type' => 'integer', 'belong_id' => 'integer', 'rank' => 'integer', 'status' => 'integer'];
public static function list(int $belong_id, int $account_type, string $post_name)
{
$model = self::where('belong_id', $belong_id)
->where('account_type', $account_type);
if ($post_name != '') {
$model = $model->where('post_name', "like", "%$post_name%");
}
return $model->orderByDesc("rank")->orderByDesc("post_id")
->select(["post_id", "post_name", "rank", "status", "create_time"])
->get()->toArray();
}
public static function options(int $belong_id, int $account_type)
{
return self::where('belong_id', $belong_id)
->where('account_type', $account_type)
->where("status",1)
->orderByDesc("rank")->orderByDesc("post_id")
->select(["post_id", "post_name"])
->get()->toArray();
}
}

View File

@ -7,16 +7,16 @@ namespace App\Model;
use Hyperf\DbConnection\Db;
/**
* @property int $role_id
* @property string $role_name
* @property int $account_type
* @property int $belong_id
* @property string $checked_menus
* @property int $status
* @property int $rank
* @property string $deleted_at
* @property string $create_time
* @property string $update_time
* @property int $role_id
* @property string $role_name
* @property int $account_type
* @property int $belong_id
* @property string $checked_menus
* @property int $status
* @property int $rank
* @property string $deleted_at
* @property string $create_time
* @property string $update_time
*/
class Role extends Model
{
@ -42,10 +42,10 @@ class Role extends Model
$model = self::where('belong_id', $belong_id)
->where('account_type', $account_type);
if ($role_name != '') {
$model = $model->where("role_name","like", "%$role_name%");
$model = $model->where("role_name", "like", "%$role_name%");
}
return $model->select(["role_id","role_name","status","create_time","rank","checked_menus"])
->get()->each(function ($item){
return $model->select(["role_id", "role_name", "status", "create_time", "rank", "checked_menus"])
->get()->each(function ($item) {
$item['menus'] = RoleMenu::getMenu($item['role_id']);
})->toArray();
}
@ -53,9 +53,10 @@ class Role extends Model
public static function options(int $belong_id, int $account_type)
{
return self::where('belong_id', $belong_id)
->where("status", 1)
->where('account_type', $account_type)
->orderByDesc("rank")
->select(["role_id","role_name"])
->select(["role_id", "role_name"])
->get()->toArray();
}

View File

@ -15,9 +15,8 @@ class Account extends FormRequest
'login' => ['username', 'password', 'uuid', 'code'],
'sy_login' => ['username', 'password'],
'info' => ['realname', 'avatar'],
'add' => ['realname','username','password'],
'edit' => ['realname','username','account_id'],
'edit_bank' => ['acc_name','acc_no','idcard','acc_phone','bank_name','idcard_front_pic','idcard_back_pic','acc_front_pic']
'add' => ['username','password'],
'edit' => ['username','account_id']
];
/**
@ -43,12 +42,6 @@ class Account extends FormRequest
'account_id' => 'required',
'acc_name' => 'required',
'acc_no' => 'required',
'idcard' => 'required',
'acc_phone' => 'required',
'bank_name' => 'required',
'idcard_front_pic' => 'required',
'idcard_back_pic' => 'required',
'acc_front_pic' => 'required'
];
}
@ -56,16 +49,7 @@ class Account extends FormRequest
{
return [
'code.required' => '验证码必填!',
'realname.required' => '姓名必填!',
'avatar.required' => '头像必填!',
'acc_name.required' => '开户名称必填!',
'acc_no.required' => '银行卡号必填!',
'idcard.required' => '身份证号必填!',
'acc_phone.required' => '银行预留手机号必填!',
'bank_name.required' => '开户行名称必填!',
'idcard_front_pic.required' => '身份证正面必传!',
'idcard_back_pic.required' => '身份证反面必传!',
'acc_front_pic.required' => '结算卡正面必传!',
'username.required' => '用户名必填!'
];
}
}

43
app/Request/Post.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace App\Request;
use Hyperf\Validation\Request\FormRequest;
/**
* 菜单
*/
class Post extends FormRequest
{
protected array $scenes = [
'add' => ['post_name'],
'edit' => ['post_id', 'post_name'],
];
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'post_id' => 'required',
'post_name' => 'required'
];
}
public function messages(): array
{
return [
'post_id.required' => '岗位ID必填',
'post_name.required' => '岗位名称必填!'
];
}
}

View File

@ -5,6 +5,8 @@
namespace App\Utils;
use function Hyperf\Support\make;
trait Crud
{
public static function add(array $data)
@ -15,11 +17,19 @@ trait Crud
public static function edit(array $data)
{
return self::where("menu_id", $data['menu_id'])->update($data);
$model = make(static::class);
return $model->where($model->primaryKey, $data[$model->primaryKey])->update($data);
}
public static function del(string $ids): int
{
return self::destroy(explode(",", $ids));
}
public static function getById(int $id, array $field = ['*']): array
{
$model = make(static::class);
$info = $model->where($model->primaryKey, $id)->select($field)->first();
return $info ? $info->toArray() : [];
}
}

View File

@ -26,6 +26,7 @@
"hyperf/http-server": "~3.1.0",
"hyperf/logger": "~3.1.0",
"hyperf/memory": "~3.1.0",
"hyperf/paginator": "^3.1",
"hyperf/phar": "^3.1",
"hyperf/process": "~3.1.0",
"hyperf/rate-limit": "^3.1",

View File

@ -14,6 +14,7 @@ return [
'http' => [
Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
App\Exception\Handler\AppExceptionHandler::class,
App\Exception\Handler\ValidationExceptionHandler::class,
],
],
];