262 lines
8.2 KiB
PHP
262 lines
8.2 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace app\admin\controller;
|
||
|
||
use app\admin\BaseController;
|
||
use think\exception\ValidateException;
|
||
use think\facade\Db;
|
||
use think\facade\Session;
|
||
use think\response\Json;
|
||
use think\db\exception\DbException;
|
||
use app\model\FrontMenu;
|
||
|
||
class FrontMenuController extends BaseController
|
||
{
|
||
/**
|
||
* 获取前端导航接口
|
||
* @return \think\response\Json
|
||
*/
|
||
public function getFrontMenus()
|
||
{
|
||
try {
|
||
// 获取所有未删除的菜单
|
||
$frontMenus = FrontMenu::where('delete_time', null)
|
||
->field('id,pid,title,type,image,path,component_path,sort,desc')
|
||
->order('sort', 'desc')
|
||
->select()
|
||
->toArray(); // 转换为数组
|
||
|
||
// 使用 buildFrontMenuTree 构建树形结构
|
||
$treeFrontMenus = $this->buildFrontMenuTree($frontMenus);
|
||
|
||
return json([
|
||
'code' => 200,
|
||
'msg' => 'success',
|
||
'data' => $treeFrontMenus
|
||
]);
|
||
} catch (DbException $e) {
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail:' . $e->getMessage(),
|
||
'data' => $e->getTraceAsString()
|
||
]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 创建新菜单
|
||
* @return \think\response\Json
|
||
*/
|
||
public function createFrontMenu()
|
||
{
|
||
try {
|
||
// 获取请求参数
|
||
$data = $this->request->param();
|
||
|
||
// 验证参数
|
||
$this->validate($data, [
|
||
'title|菜单名称' => 'require|max:50',
|
||
'pid|上级菜单ID' => 'integer',
|
||
'type|菜单类型' => 'require|in:1,2,3,4',
|
||
'sort|排序号' => 'integer',
|
||
'path|路由路径' => 'max:200',
|
||
'component_path|组件路径' => 'max:200',
|
||
'desc|描述' => 'max:500',
|
||
]);
|
||
|
||
// 准备菜单数据
|
||
$menuData = [
|
||
'pid' => $data['pid'] ?? 0,
|
||
'title' => $data['title'],
|
||
'type' => $data['type'],
|
||
'sort' => $data['sort'] ?? 0,
|
||
'path' => $data['path'] ?? '',
|
||
'component_path' => $data['component_path'] ?? '',
|
||
'image' => $data['image'] ?? '',
|
||
'desc' => $data['desc'] ?? '',
|
||
'create_time' => date('Y-m-d H:i:s')
|
||
];
|
||
|
||
// 创建菜单
|
||
$result = FrontMenu::insertGetId($menuData);
|
||
|
||
if ($result === false) {
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail'
|
||
]);
|
||
}
|
||
|
||
// 记录操作日志
|
||
$this->logSuccess('前端导航管理', '创建前端导航', ['id' => $result]);
|
||
return json([
|
||
'code' => 200,
|
||
'msg' => 'success'
|
||
]);
|
||
} catch (ValidateException $e) {
|
||
// 记录失败日志
|
||
$this->logFail('前端导航管理', '创建前端导航', $e->getMessage());
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail:' . $e->getMessage()
|
||
]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 编辑前端导航
|
||
* @param int $id 前端导航ID
|
||
* @return \think\response\Json
|
||
*/
|
||
public function editFrontMenu(int $id)
|
||
{
|
||
try {
|
||
// 获取请求参数
|
||
$data = $this->request->param();
|
||
|
||
// 验证参数
|
||
$this->validate($data, [
|
||
'title|菜单名称' => 'require|max:50',
|
||
'pid|上级菜单ID' => 'integer',
|
||
'type|菜单类型' => 'require|in:1,2,3,4',
|
||
'sort|排序号' => 'integer',
|
||
'path|路由路径' => 'max:200',
|
||
'component_path|组件路径' => 'max:200',
|
||
'desc|描述' => 'max:500',
|
||
]);
|
||
|
||
// 准备更新数据
|
||
$updateData = [
|
||
'title' => $data['title'],
|
||
'pid' => $data['pid'] ?? null,
|
||
'type' => $data['type'],
|
||
'path' => $data['path'] ?? null,
|
||
'component_path' => $data['component_path'] ?? null,
|
||
'image' => $data['image'] ?? null,
|
||
'desc' => $data['desc'] ?? null,
|
||
'sort' => $data['sort'] ?? 0,
|
||
'update_time' => date('Y-m-d H:i:s')
|
||
];
|
||
|
||
// 执行更新
|
||
FrontMenu::where('id', $id)->update($updateData);
|
||
|
||
// 获取更新后的菜单信息
|
||
$menu = FrontMenu::where('id', $id)->find();
|
||
|
||
// 记录操作日志
|
||
$this->logSuccess('前端导航管理', '更新前端导航', ['id' => $id]);
|
||
return json([
|
||
'code' => 200,
|
||
'msg' => 'success',
|
||
'data' => $menu ? $menu->toArray() : []
|
||
]);
|
||
} catch (ValidateException $e) {
|
||
// 记录失败日志
|
||
$this->logFail('前端导航管理', '更新前端导航', $e->getMessage());
|
||
return json([
|
||
'code' => 400,
|
||
'msg' => $e->getError()
|
||
]);
|
||
} catch (DbException $e) {
|
||
// 记录失败日志
|
||
$this->logFail('前端导航管理', '更新前端导航', $e->getMessage());
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail:' . $e->getMessage(),
|
||
'data' => $e->getTraceAsString()
|
||
]);
|
||
}
|
||
}
|
||
|
||
|
||
public function deleteFrontMenu(int $id)
|
||
{
|
||
try {
|
||
// 检查是否有子前端导航
|
||
$hasChildren = FrontMenu::where('pid', $id)
|
||
->where('pid', $id)
|
||
->where('delete_time', null)
|
||
->count() > 0;
|
||
|
||
if ($hasChildren) {
|
||
return json([
|
||
'code' => 400,
|
||
'msg' => '该前端导航下有子导航,无法删除'
|
||
]);
|
||
}
|
||
|
||
// 逻辑删除前端导航
|
||
$result = FrontMenu::where('id', $id)
|
||
->where('id', $id)
|
||
->where('delete_time', null)
|
||
->update([
|
||
'delete_time' => date('Y-m-d H:i:s'),
|
||
'update_time' => date('Y-m-d H:i:s')
|
||
]);
|
||
|
||
if ($result === false) {
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail'
|
||
]);
|
||
}
|
||
|
||
// 记录操作日志
|
||
$this->logSuccess('前端导航管理', '删除前端导航', ['id' => $id]);
|
||
return json([
|
||
'code' => 200,
|
||
'msg' => 'success'
|
||
]);
|
||
} catch (ValidateException $e) {
|
||
// 记录失败日志
|
||
$this->logFail('前端导航管理', '删除前端导航', $e->getMessage());
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail:' . $e->getMessage()
|
||
]);
|
||
} catch (DbException $e) {
|
||
// 记录失败日志
|
||
$this->logFail('前端导航管理', '删除前端导航', $e->getMessage());
|
||
return json([
|
||
'code' => 500,
|
||
'msg' => 'fail:' . $e->getMessage()
|
||
]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 构建前端导航树形结构
|
||
* @param array $frontMenus 前端导航列表
|
||
* @param int $pid 父前端导航ID
|
||
* @return array
|
||
*/
|
||
private function buildFrontMenuTree(array $frontMenus, int $pid = 0): array
|
||
{
|
||
$tree = [];
|
||
|
||
foreach ($frontMenus as $frontMenu) {
|
||
// 将null的pid视为0处理
|
||
$menuPid = is_null($frontMenu['pid']) ? 0 : $frontMenu['pid'];
|
||
if ($menuPid == $pid) {
|
||
$children = $this->buildFrontMenuTree($frontMenus, $frontMenu['id']);
|
||
if (!empty($children)) {
|
||
$frontMenu['children'] = $children;
|
||
}
|
||
$tree[] = $frontMenu;
|
||
}
|
||
}
|
||
|
||
// 按 sort 字段降序排序
|
||
usort($tree, function ($a, $b) {
|
||
$sortA = $a['sort'] ?? 0;
|
||
$sortB = $b['sort'] ?? 0;
|
||
return $sortB - $sortA;
|
||
});
|
||
|
||
return $tree;
|
||
}
|
||
}
|