MenuController.php 10.9 KB
Newer Older
孙建华 已提交
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * Date: 2019/2/25 Time: 14:49
 *
 * @author  Eddy <cumtsjh@163.com>
 * @version v1.0.0
 */

namespace App\Http\Controllers\Admin;

孙建华 已提交
11
use App\Events\MenuUpdated;
孙建华 已提交
12 13 14 15 16 17
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\MenuRequest;
use App\Model\Admin\Menu;
use App\Repository\Admin\MenuRepository;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
孙建华 已提交
18
use Illuminate\Routing\Exceptions\UrlGenerationException;
孙建华 已提交
19 20 21 22 23 24
use Illuminate\Support\Str;
use Log;
use Route;

class MenuController extends Controller
{
孙建华 已提交
25
    protected $formNames = ['name', 'pid', 'status', 'order', 'route', 'group', 'remark', 'url', 'is_lock_name'];
孙建华 已提交
26 27 28 29 30 31 32 33 34

    public function __construct()
    {
        parent::__construct();

        $this->breadcrumb[] = ['title' => '菜单管理', 'url' => route('admin::menu.index')];
    }

    /**
孙建华 已提交
35
     * 菜单管理-菜单列表
孙建华 已提交
36 37 38 39 40 41 42 43 44
     *
     */
    public function index()
    {
        $this->breadcrumb[] = ['title' => '菜单列表', 'url' => ''];
        return view('admin.menu.index', ['breadcrumb' => $this->breadcrumb]);
    }

    /**
孙建华 已提交
45
     * 菜单管理-菜单列表数据
孙建华 已提交
46 47 48 49 50 51 52
     *
     * @param Request $request
     */
    public function list(Request $request)
    {
        $perPage = (int) $request->get('limit', 50);
        $action = $request->get('action');
E
eddy8 已提交
53
        $this->formNames[] = 'created_at';
孙建华 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
        $condition = $request->only($this->formNames);

        if (isset($condition['pid'])) {
            $condition['pid'] = ['=', $condition['pid']];
        } else {
            if ($action !== 'search') {
                $condition['pid'] = ['=', 0];
            }
        }

        $data = MenuRepository::list($perPage, $condition);

        return $data;
    }

    /**
孙建华 已提交
70
     * 菜单管理-新增菜单
孙建华 已提交
71 72 73 74 75 76 77 78 79 80
     *
     */
    public function create()
    {
        //dd(\App\Repository\Admin\MenuRepository::tree());
        $this->breadcrumb[] = ['title' => '新增菜单', 'url' => ''];
        return view('admin.menu.add', ['breadcrumb' => $this->breadcrumb]);
    }

    /**
孙建华 已提交
81
     * 菜单管理-保存菜单
孙建华 已提交
82 83 84 85 86 87 88
     *
     * @param MenuRequest $request
     * @return array
     */
    public function save(MenuRequest $request)
    {
        try {
孙建华 已提交
89
            MenuRepository::add(array_merge($request->only($this->formNames), ['guard_name' => 'admin']));
孙建华 已提交
90
            event(new MenuUpdated());
孙建华 已提交
91 92 93
            return [
                'code' => 0,
                'msg' => '新增成功',
孙建华 已提交
94
                'redirect' => true
孙建华 已提交
95 96 97 98 99
            ];
        } catch (QueryException $e) {
            return [
                'code' => 1,
                'msg' => '新增失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前菜单已存在' : '其它错误'),
孙建华 已提交
100
                'redirect' => false
孙建华 已提交
101 102 103 104 105
            ];
        }
    }

    /**
孙建华 已提交
106
     * 菜单管理-编辑菜单
孙建华 已提交
107 108 109 110 111 112 113 114 115 116 117 118
     *
     * @param int $id
     */
    public function edit($id)
    {
        $this->breadcrumb[] = ['title' => '编辑菜单', 'url' => ''];

        $model = MenuRepository::find($id);
        return view('admin.menu.add', ['id' => $id, 'model' => $model, 'breadcrumb' => $this->breadcrumb]);
    }

    /**
孙建华 已提交
119
     * 菜单管理-更新菜单
孙建华 已提交
120 121 122
     *
     * @param MenuRequest $request
     * @param int $id
孙建华 已提交
123
     * @return array
孙建华 已提交
124 125 126
     */
    public function update(MenuRequest $request, $id)
    {
孙建华 已提交
127 128 129 130 131 132 133
        $data = array_merge(
            [
                'is_lock_name' => Menu::UNLOCK_NAME,
                'status' => Menu::STATUS_DISABLE
            ],
            $request->only($this->formNames)
        );
孙建华 已提交
134 135 136

        try {
            MenuRepository::update($id, $data);
孙建华 已提交
137
            event(new MenuUpdated());
孙建华 已提交
138 139 140
            return [
                'code' => 0,
                'msg' => '编辑成功',
孙建华 已提交
141
                'redirect' => true
孙建华 已提交
142 143 144 145 146
            ];
        } catch (QueryException $e) {
            return [
                'code' => 1,
                'msg' => '编辑失败:' . (Str::contains($e->getMessage(), 'Duplicate entry') ? '当前菜单已存在' : '其它错误'),
孙建华 已提交
147
                'redirect' => false
孙建华 已提交
148 149 150
            ];
        }
    }
孙建华 已提交
151

孙建华 已提交
152 153 154 155 156
    /**
     * 菜单管理-删除菜单
     *
     * @param int $id
     */
孙建华 已提交
157
    public function delete($id)
孙建华 已提交
158
    {
孙建华 已提交
159 160
        try {
            MenuRepository::delete($id);
孙建华 已提交
161
            event(new MenuUpdated());
孙建华 已提交
162 163 164
            return [
                'code' => 0,
                'msg' => '删除成功',
孙建华 已提交
165
                'redirect' => true
孙建华 已提交
166 167 168 169 170
            ];
        } catch (\RuntimeException $e) {
            return [
                'code' => 1,
                'msg' => '删除失败:' . $e->getMessage(),
孙建华 已提交
171
                'redirect' => false
孙建华 已提交
172 173
            ];
        }
孙建华 已提交
174 175
    }

孙建华 已提交
176 177 178 179 180 181
    /**
     * 菜单管理-自动更新菜单
     *
     * @return array
     * @throws \ReflectionException
     */
孙建华 已提交
182 183
    public function discovery()
    {
孙建华 已提交
184 185
        $addNum = 0;
        $updateNum = 0;
孙建华 已提交
186 187

        foreach (Route::getRoutes()->getRoutesByName() as $k => $v) {
孙建华 已提交
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
            if (Str::startsWith($k, 'admin::')) {
                // 取方法的第一行注释作为菜单的名称、分组名。格式:分组名称-菜单名称。未写分组名称,则注释直接作为菜单名称。未写注释则选用uri作为菜单名称。
                $action = explode('@', $v->getActionName());
                if (!method_exists($action[0], $action[1])) {
                    continue;
                }
                $reflection = new \ReflectionMethod($action[0], $action[1]);
                $comment = trim(array_get(explode("\n", $reflection->getDocComment()), 1, ''), " \t\n\r\0\x0B*");
                if ($comment === '') {
                    $data['name'] = $v->uri;
                    $data['group'] = '';
                } else {
                    if (Str::contains($comment, '-')) {
                        $arr = explode('-', $comment);
                        $data['name'] = trim($arr[1]);
                        $data['group'] = trim($arr[0]);
                    } else {
                        $data['name'] = trim($comment);
                        $data['group'] = '';
                    }
                }

                $data['route'] = $k;
211
                $data['guard_name'] = 'admin';
孙建华 已提交
212
                if (in_array('GET', $v->methods) && !Str::contains($v->uri, '{')) {
孙建华 已提交
213 214 215 216
                    $data['status'] = Menu::STATUS_ENABLE;
                } else {
                    $data['status'] = Menu::STATUS_DISABLE;
                }
孙建华 已提交
217 218 219 220 221
                try {
                    $data['url'] = route($k, [], false);
                } catch (UrlGenerationException $e) {
                    $data['url'] = '';
                }
孙建华 已提交
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
                try {
                    $model = MenuRepository::exist($k);
                    if ($model) {
                        if ($model->is_lock_name === Menu::UNLOCK_NAME &&
                            ($model->name != $data['name'] || $model->group != $data['group'])) {
                            unset($data['status']);
                            MenuRepository::update($model->id, $data);
                            $updateNum++;
                        }
                    } else {
                        MenuRepository::add($data);
                        $addNum++;
                    }
                } catch (QueryException $e) {
                    if ($addNum > 0 || $updateNum > 0) {
                        event(new MenuUpdated());
                    }

                    if ($e->getCode() == 23000) {
                        return [
                            'code' => 1,
                            'msg' => "唯一性冲突:请检查菜单名称或路由名称。name: {$data['name']} route: {$data['route']}",
                        ];
                    } else {
                        return [
                            'code' => 2,
                            'msg' => $e->getMessage(),
                        ];
孙建华 已提交
251
                    }
孙建华 已提交
252
                }
孙建华 已提交
253 254 255
            }
        }

孙建华 已提交
256 257 258
        if ($addNum > 0 || $updateNum > 0) {
            event(new MenuUpdated());
        }
孙建华 已提交
259 260
        return [
            'code' => 0,
孙建华 已提交
261
            'msg' => "更新成功。新增菜单数:{$addNum},更新菜单数:{$updateNum}。",
孙建华 已提交
262
            'redirect' => true
孙建华 已提交
263 264
        ];
    }
孙建华 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282

    /**
     * 菜单管理-批量操作
     */
    public function batch(Request $request)
    {
        $type = $request->input('type', '');
        $ids = $request->input('ids');
        if (!is_array($ids)) {
            return [
                'code' => 1,
                'msg' => '参数错误'
            ];
        }
        $ids = array_map(function ($item) {
            return intval($item);
        }, $ids);

孙建华 已提交
283
        $message = '';
孙建华 已提交
284 285 286 287 288 289 290
        switch ($type) {
            case 'disable':
                Menu::query()->whereIn('id', $ids)->update(['status' => Menu::STATUS_DISABLE]);
                break;
            case 'enable':
                Menu::query()->whereIn('id', $ids)->update(['status' => Menu::STATUS_ENABLE]);
                break;
孙建华 已提交
291
            case 'delete':
孙建华 已提交
292 293 294 295 296 297
                // 过滤掉有子项目的
                $hasChildren = array_unique(Menu::query()->whereIn('pid', $ids)->pluck('pid')->toArray());
                $deleteIds = array_diff($ids, $hasChildren);
                if (!empty($deleteIds)) {
                    Menu::query()->whereIn('id', $deleteIds)->delete();
                }
孙建华 已提交
298
                if (!empty($hasChildren)) {
孙建华 已提交
299 300
                    $message = ' 以下菜单ID因有子菜单不能直接删除:' . implode(',', $hasChildren);
                }
孙建华 已提交
301
                break;
孙建华 已提交
302 303 304 305 306 307 308 309
            case 'parent':
                $pid = intval($request->input('params', -1));
                if ($pid < 0 || ($pid > 0 && !MenuRepository::find($pid))) {
                    return [
                        'code' => 2,
                        'msg' => '父级菜单ID错误'
                    ];
                }
孙建华 已提交
310 311 312 313 314 315
                if (in_array($pid, $ids)) {
                    return [
                        'code' => 3,
                        'msg' => '不能将父级菜单指定为自身'
                    ];
                }
孙建华 已提交
316 317
                Menu::query()->whereIn('id', $ids)->update(['pid' => $pid]);
                break;
318 319 320 321 322 323 324 325 326 327
            case 'order':
                $order = intval($request->input('params', 77));
                if ($order < 0) {
                    return [
                        'code' => 4,
                        'msg' => '排序值不能小于0'
                    ];
                }
                Menu::query()->whereIn('id', $ids)->update(['order' => $order]);
                break;
328 329 330 331
            case 'group':
                $group = strval($request->input('params', ''));
                Menu::query()->whereIn('id', $ids)->update(['group' => $group]);
                break;
332 333 334
            case 'lock_name':
                Menu::query()->whereIn('id', $ids)->update(['is_lock_name' => Menu::LOCK_NAME]);
                break;
孙建华 已提交
335 336 337 338
            default:
                break;
        }

孙建华 已提交
339
        event(new MenuUpdated());
孙建华 已提交
340 341
        return [
            'code' => 0,
孙建华 已提交
342
            'msg' => '操作成功' . $message,
孙建华 已提交
343 344 345
            'reload' => true
        ];
    }
孙建华 已提交
346
}