""" 后台导航管理视图(需要登录 + 权限码 system:nav:*) 提供 Nav 模型的 CRUD 接口,供后台管理员维护前台公开导航。 """ from flask import Blueprint, render_template, request from flask_login import current_user from applications.common.utils.http import table_api, fail_api, success_api from applications.common.utils.rights import authorize from applications.common.utils.validate import str_escape from applications.extensions import db from applications.extensions.init_limit import limiter from applications.models import Nav from applications.schemas import NavManageSchema bp = Blueprint('nav', __name__, url_prefix='/nav') @bp.get('/') @authorize("system:nav:main") def main(): """导航管理主页""" return render_template('system/nav/main.html') @bp.get('/data') @limiter.limit("60 per minute") @authorize("system:nav:main") def data(): """表格数据接口""" keyword = str_escape(request.args.get('keyword', type=str)) category = str_escape(request.args.get('category', type=str)) query = Nav.query if keyword: query = query.filter( db.or_( Nav.title.contains(keyword), Nav.url.contains(keyword), Nav.description.contains(keyword), ) ) if category: query = query.filter(Nav.category == category) items = query.order_by(Nav.category.asc(), Nav.sort.asc(), Nav.id.asc()).all() data = NavManageSchema(many=True).dump(items) return table_api(msg="请求成功", data=data, count=len(data)) @bp.get('/add') @authorize("system:nav:add", log=True) def add(): return render_template('system/nav/add.html') @bp.post('/save') @authorize("system:nav:add", log=True) def save(): req = request.get_json(force=True) try: nav = Nav( category=str_escape(req.get('category')), title=str_escape(req.get('title')), url=str_escape(req.get('url')), description=str_escape(req.get('description')), icon=str_escape(req.get('icon')) or 'layui-icon-link', sort=int(req.get('sort') or 0), status=int(req.get('status') or 1), is_external=int(req.get('isExternal') or 1), create_by=current_user.username if current_user.is_authenticated else 'admin', ) db.session.add(nav) db.session.commit() except Exception as e: db.session.rollback() return fail_api(msg=f"新增失败:{e}") return success_api(msg="新增成功") @bp.get('/edit') @authorize("system:nav:edit", log=True) def edit(): nav_id = request.args.get("navId", type=int) nav = Nav.query.get(nav_id) if not nav: return fail_api(msg="导航不存在") return render_template('system/nav/edit.html', nav=nav) @bp.put('/update') @authorize("system:nav:edit", log=True) def update(): req = request.get_json(force=True) nav_id = req.get('id') nav = Nav.query.get(nav_id) if not nav: return fail_api(msg="导航不存在") try: nav.category = str_escape(req.get('category')) or nav.category nav.title = str_escape(req.get('title')) or nav.title nav.url = str_escape(req.get('url')) or nav.url nav.description = str_escape(req.get('description')) nav.icon = str_escape(req.get('icon')) or 'layui-icon-link' nav.sort = int(req.get('sort') or 0) nav.status = int(req.get('status') or 1) nav.is_external = int(req.get('isExternal') or 1) db.session.commit() except Exception as e: db.session.rollback() return fail_api(msg=f"更新失败:{e}") return success_api(msg="更新成功") @bp.delete('/remove/') @authorize("system:nav:remove", log=True) def remove(_id): nav = Nav.query.get(_id) if not nav: return fail_api(msg="导航不存在") db.session.delete(nav) db.session.commit() return success_api(msg="删除成功") @bp.put('/enable') @authorize("system:nav:edit", log=True) def enable(): nav_id = request.get_json(force=True).get('navId') Nav.query.filter_by(id=nav_id).update({"status": 1}) db.session.commit() return success_api(msg="已启用") @bp.put('/disable') @authorize("system:nav:edit", log=True) def disable(): nav_id = request.get_json(force=True).get('navId') Nav.query.filter_by(id=nav_id).update({"status": 0}) db.session.commit() return success_api(msg="已禁用")