mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 23:42:48 +08:00
309 lines
8.6 KiB
PHP
309 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace base\common\service;
|
|
|
|
use app\common\constants\MenuConstant;
|
|
use app\common\service\AuthService;
|
|
use think\facade\Db;
|
|
|
|
class MenuServiceBase
|
|
{
|
|
/**
|
|
* 管理员ID.
|
|
* @var int
|
|
*/
|
|
protected $adminId;
|
|
|
|
public function __construct($adminId)
|
|
{
|
|
$this->adminId = $adminId;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 获取首页信息.
|
|
* @return array|\think\Model|null
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public function getHomeInfo()
|
|
{
|
|
$data = Db::name('system_menu')
|
|
->field('title,icon,href')
|
|
->where('delete_time', 0)
|
|
->where('pid', MenuConstant::HOME_PID)
|
|
->find();
|
|
!empty($data) && $data['href'] = __url($data['href']);
|
|
|
|
$data['mb_title'] = '菜单';
|
|
$data['mb_href'] = (string)url('admin/Index/mobile');
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 获取后台菜单树信息.
|
|
* @return mixed
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public function getMenuTree()
|
|
{
|
|
/** @var AuthService $authService */
|
|
$authServer = app(AuthService::class, ['adminId' => $this->adminId]);
|
|
|
|
return $this->buildMenuChild(0, $this->getMenuData(), $authServer);
|
|
}
|
|
|
|
private function buildMenuChild($pid, $menuList, AuthService $authServer)
|
|
{
|
|
$treeList = [];
|
|
foreach ($menuList as &$v) {
|
|
$check = false;
|
|
if (!empty($v['auth_node'])) {
|
|
$check = $authServer->checkNode($v['auth_node']);
|
|
} elseif (!empty($v['href'])) {
|
|
$check = $authServer->checkNode($v['href']);
|
|
} else {
|
|
$check = true;
|
|
}
|
|
|
|
!empty($v['href']) && $v['href'] = __url($v['href']);
|
|
if ($pid == $v['pid'] && $check) {
|
|
$node = $v;
|
|
$child = $this->buildMenuChild($v['id'], $menuList, $authServer);
|
|
if (!empty($child)) {
|
|
$node['child'] = $child;
|
|
}
|
|
if (!empty($v['href']) || !empty($child)) {
|
|
$treeList[] = $node;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $treeList;
|
|
}
|
|
|
|
/**
|
|
* 获取所有菜单数据.
|
|
* @return \think\Collection
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
protected function getMenuData()
|
|
{
|
|
$menuData = Db::name('system_menu')
|
|
->field('id,pid,title,icon,href,target,auth_node')
|
|
->where('delete_time', 0)
|
|
->where([
|
|
['status', '=', '1'],
|
|
['pid', '<>', MenuConstant::HOME_PID],
|
|
])
|
|
->order([
|
|
'sort' => 'desc',
|
|
'id' => 'asc',
|
|
])
|
|
->select();
|
|
|
|
return $menuData;
|
|
}
|
|
|
|
/**
|
|
* 创建菜单
|
|
*
|
|
* @param array $data 菜单数据
|
|
* @return int 返回新创建的菜单ID
|
|
* @throws \Exception
|
|
*/
|
|
public function create(array $data): int
|
|
{
|
|
$menu = Db::name('system_menu');
|
|
|
|
// 准备数据
|
|
$insertData = [
|
|
'pid' => $data['parent_id'] ?? 0,
|
|
'title' => $data['title'] ?? '',
|
|
'icon' => $data['icon'] ?? '',
|
|
'href' => $data['path'] ?? '',
|
|
'auth_node' => $data['node'] ?? '',
|
|
'sort' => $data['sort'] ?? 100,
|
|
'status' => 1,
|
|
'target' => '_self',
|
|
'remark' => $data['remark'] ?? '',
|
|
'create_time' => time(),
|
|
'update_time' => time(),
|
|
'delete_time' => 0,
|
|
];
|
|
|
|
// 验证必填字段
|
|
if (empty($insertData['title'])) {
|
|
throw new \Exception('菜单标题不能为空');
|
|
}
|
|
|
|
// 验证父菜单是否存在
|
|
if ($insertData['pid'] > 0) {
|
|
$parentMenu = Db::name('system_menu')
|
|
->where('id', $insertData['pid'])
|
|
->where('delete_time', 0)
|
|
->find();
|
|
if (empty($parentMenu)) {
|
|
throw new \Exception("父菜单ID {$insertData['pid']} 不存在");
|
|
}
|
|
}
|
|
|
|
// 插入数据
|
|
$menuId = $menu->insertGetId($insertData);
|
|
|
|
if (!$menuId) {
|
|
throw new \Exception('菜单创建失败');
|
|
}
|
|
|
|
return (int)$menuId;
|
|
}
|
|
|
|
/**
|
|
* 更新菜单
|
|
*
|
|
* @param int $menuId 菜单ID
|
|
* @param array $data 更新数据
|
|
* @return bool 是否更新成功
|
|
* @throws \Exception
|
|
*/
|
|
public function update(int $menuId, array $data): bool
|
|
{
|
|
// 验证菜单是否存在
|
|
$menu = Db::name('system_menu')
|
|
->where('id', $menuId)
|
|
->where('delete_time', 0)
|
|
->find();
|
|
|
|
if (empty($menu)) {
|
|
throw new \Exception("菜单ID {$menuId} 不存在");
|
|
}
|
|
|
|
// 准备更新数据
|
|
$updateData = [
|
|
'update_time' => time(),
|
|
];
|
|
|
|
if (isset($data['title'])) {
|
|
$updateData['title'] = $data['title'];
|
|
}
|
|
if (isset($data['parent_id'])) {
|
|
$updateData['pid'] = $data['parent_id'];
|
|
}
|
|
if (isset($data['icon'])) {
|
|
$updateData['icon'] = $data['icon'];
|
|
}
|
|
if (isset($data['path'])) {
|
|
$updateData['href'] = $data['path'];
|
|
}
|
|
if (isset($data['node'])) {
|
|
$updateData['auth_node'] = $data['node'];
|
|
}
|
|
if (isset($data['sort'])) {
|
|
$updateData['sort'] = $data['sort'];
|
|
}
|
|
if (isset($data['status'])) {
|
|
$updateData['status'] = $data['status'];
|
|
}
|
|
if (isset($data['remark'])) {
|
|
$updateData['remark'] = $data['remark'];
|
|
}
|
|
if (isset($data['target'])) {
|
|
$updateData['target'] = $data['target'];
|
|
}
|
|
|
|
// 验证必填字段
|
|
if (empty($menu['title']) && empty($updateData['title'])) {
|
|
throw new \Exception('菜单标题不能为空');
|
|
}
|
|
|
|
// 验证父菜单是否存在(如果修改了父菜单)
|
|
if (isset($updateData['pid']) && $updateData['pid'] > 0) {
|
|
// 不能将自己设置为父菜单
|
|
if ($updateData['pid'] == $menuId) {
|
|
throw new \Exception('不能将自己设置为父菜单');
|
|
}
|
|
|
|
$parentMenu = Db::name('system_menu')
|
|
->where('id', $updateData['pid'])
|
|
->where('delete_time', 0)
|
|
->find();
|
|
if (empty($parentMenu)) {
|
|
throw new \Exception("父菜单ID {$updateData['pid']} 不存在");
|
|
}
|
|
}
|
|
|
|
// 更新数据
|
|
$result = Db::name('system_menu')
|
|
->where('id', $menuId)
|
|
->update($updateData);
|
|
|
|
return $result !== false;
|
|
}
|
|
|
|
/**
|
|
* 删除菜单
|
|
*
|
|
* @param int $menuId 菜单ID
|
|
* @return bool 是否删除成功
|
|
* @throws \Exception
|
|
*/
|
|
public function delete(int $menuId): bool
|
|
{
|
|
// 验证菜单是否存在
|
|
$menu = Db::name('system_menu')
|
|
->where('id', $menuId)
|
|
->where('delete_time', 0)
|
|
->find();
|
|
|
|
if (empty($menu)) {
|
|
throw new \Exception("菜单ID {$menuId} 不存在");
|
|
}
|
|
|
|
// 检查是否有子菜单
|
|
$hasChildren = Db::name('system_menu')
|
|
->where('pid', $menuId)
|
|
->where('delete_time', 0)
|
|
->count();
|
|
|
|
if ($hasChildren > 0) {
|
|
throw new \Exception('该菜单下存在子菜单,请先删除子菜单');
|
|
}
|
|
|
|
// 软删除
|
|
$result = Db::name('system_menu')
|
|
->where('id', $menuId)
|
|
->update([
|
|
'delete_time' => time(),
|
|
'update_time' => time(),
|
|
]);
|
|
|
|
return $result !== false;
|
|
}
|
|
|
|
/**
|
|
* 获取菜单详情
|
|
*
|
|
* @param int $menuId 菜单ID
|
|
* @return array|null 菜单数据
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
* @throws \think\db\exception\DbException
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
*/
|
|
public function getMenu(int $menuId): ?array
|
|
{
|
|
$menu = Db::name('system_menu')
|
|
->where('id', $menuId)
|
|
->where('delete_time', 0)
|
|
->find();
|
|
|
|
return $menu ? $menu : null;
|
|
}
|
|
}
|