首页
小程序框架
后台管理系统
新后台框架
部署指南
公司介绍
首页
小程序框架
后台管理系统
新后台框架
部署指南
公司介绍
  • YLSG新框架

YLSG新框架

项目概述

框架简介与背景

YLSG后台管理系统是基于Avue 3.0框架的二次开发版本,旨在解决传统后台管理系统开发中的痛点问题。这个框架就像是一个"代码充电宝",为开发者提供了强大的CRUD功能和灵活的配置系统。

背景故事

一晃用老框架已经5年了,五年之痒也是时候换个新欢了!毕竟,和老框架的"甜蜜期"早过了 现在它动不动就给我们脸色看:运行像老牛拉破车、打开速度堪比树懒、依赖动不动玩失踪️、富文本加载看心情、表格排版自由奔放、菜单权限随心所欲...最要命的是,安全问题就像个定时炸弹!早就想换个新欢,但一直没想好理想型该长啥样 —— 简单好上手、效率爆表、能屈能伸、加密传参要稳、权限管理得像乐高一样灵活拼装

这次终于遇到真爱了!我用AVUE3 CLI打底,经过我的深度美颜 基本把上面的痛点一网打尽!菜单权限和加密传输被我调教得服服帖帖,再用mixins大法把代码量压缩到极致 —— 现在的开发体验,丝滑得像是德芙广告

但最炸裂的还得是可视化生成工具 新建菜单?目录?页面?API?连按钮和权限都能一条龙服务!直接和服务端无缝对接不说,最丧心病狂的是 —— 连自定义事件都能一键生成!规范精准又高效,这感觉简直比连续吃鸡还爽 现在的开发速度,那真的是,咻~...

核心优势与特性

开发效率优势

页面生成器
  • 一键生成:新建页面时菜单、按钮、权限一并生成
  • 可视化操作:通过可视化界面配置页面信息
  • 模板驱动:基于模板系统,确保代码一致性
CRUD混入模块
  • 代码复用:通过混入机制,大幅减少重复代码
  • 配置驱动:页面基本只需修改option配置文件,主要调整column配置
  • 权限集成:自动集成权限控制,无需手动处理

系统架构设计

技术栈架构图

YLSG后台管理系统采用了现代化的前端技术栈,就像搭建一座"数字大厦",每一层都有其特定的职责和优势。

技术栈优势分析

Vue 3 + Composition API

  • 响应式系统:基于Proxy的响应式系统,性能更优
  • 组合式API:更好的逻辑复用和类型推导
  • Tree Shaking:更好的打包优化,减少包体积

Element Plus

  • 设计一致性:统一的设计语言和交互规范
  • 组件丰富:覆盖90%以上的后台管理需求
  • 主题定制:支持多主题切换和自定义主题色样式

Vite构建工具

  • 极速启动:基于ES模块的快速冷启动
  • 热更新:毫秒级的模块热更新
  • 按需加载:支持组件的按需加载和代码分割

路由特性

动态路由

  • 根据用户权限动态生成路由
  • 支持路由懒加载和代码分割
  • 路由参数自动解析和验证

️ 权限控制

  • 路由级别的权限控制
  • 支持路由守卫和导航拦截
  • 未授权访问自动重定向

响应式路由

  • 支持移动端路由适配
  • 路由历史记录管理
  • 支持路由参数和查询参数

路由配置示例

// 路由配置结构
const routes = [
  {
    path: '/login',
    component: () => import('@/page/login/login.vue'),
    meta: { title: '登录', hidden: true }
  },
  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [
      {
        path: 'dashboard',
        component: () => import('@/page/wel/index.vue'),
        meta: { title: '首页', icon: 'dashboard' }
      }
    ]
  },
  {
    path: '/user',
    component: Layout,
    meta: { title: '用户管理', icon: 'user' },
    children: [
      {
        path: 'list',
        component: () => import('@/page/user/user.vue'),
        meta: { title: '用户列表', permission: 'user:list' }
      }
    ]
  }
]

技术栈依赖分析

"dependencies": {
    "@element-plus/icons-vue": "^2.3.1",           // Element Plus 图标库
    "@fortawesome/fontawesome-free": "^6.4.0",     // FontAwesome 免费图标库
    "@smallwei/avue": "^3.7.0",                    // 基于Element Plus的CRUD框架
    "animate.css": "^4.1.1",                       // CSS动画库
    "avue-plugin-ueditor": "^1.0.4",               // Avue集成的UEditor富文本插件
    "axios": "^0.21.1",                            // HTTP客户端
    "cnpm": "^9.4.0",                              // 淘宝NPM镜像客户端
    "crypto-js": "^4.1.1",                         // 加密库
    "dayjs": "^1.10.6",                            // 轻量级日期处理库
    "element-plus": "^2.7.3",                      // Vue 3 UI组件库
    "js-cookie": "^3.0.0",                         // Cookie操作库
    "mockjs": "^1.1.0",                            // 数据模拟库
    "nprogress": "^0.2.0",                         // 页面加载进度条
    "vite-plugin-mock": "^2.9.4",                  // Vite的Mock插件
    "vue": "^3.4.27",                              // 渐进式JavaScript框架
    "vue-i18n": "^9.1.9",                          // 国际化插件
    "vue-router": "^4.3.2",                        // 路由管理器
    "vuex": "^4.1.0"                               // 状态管理模式
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",                // Vite的Vue 3插件
    "@vue/compiler-sfc": "^3.4.27",                // Vue单文件组件编译器
    "acorn": "^8.15.0",                            // JavaScript解析器
    "acorn-walk": "^8.3.4",                        // AST遍历工具
    "astring": "^1.9.0",                           // JavaScript代码生成器
    "sass": "^1.37.5",                             // CSS预处理器
    "unplugin-auto-import": "^0.11.2",             // 自动导入插件
    "vite": "^5.2.12",                             // 前端构建工具
    "vite-plugin-compression": "^0.5.1",           // 生产环境代码压缩插件
    "vite-plugin-vue-setup-extend": "^0.4.0"       // Vue setup语法扩展插件
  }

目录结构详解

YLSG后台管理系统的目录结构就像一座"数字城市"的规划图,每个区域都有其特定的功能和职责。这种组织方式让代码管理变得井井有条,再也不用在"代码迷宫"里迷路了!️

src/
├── api/                    # API接口封装
│   └── baseInterface.js   # 基础接口(登录、用户信息等)
├── components/            # 公共组件
│   ├── basic-block/      # 基础块级组件
│   ├── basic-container/  # 基础容器组件
│   ├── basic-video/      # 视频组件
│   ├── error-page/       # 错误页面组件
│   ├── file-manager/     # 文件管理组件
│   ├── iframe/           # 内嵌框架组件
│   ├── loginBase/        # 登录相关组件
│   └── Userinfo/         # 用户信息组件(头像,姓名,手机号)
├── config/               # 系统配置
│   ├── settings.js       # 全局系统配置
│   ├── avue_cofig.js     # Avue框架配置
│   └── loader.js         # 动态加载器配置
├── lang/                 # 国际化语言包
│   ├── index.js          # 语言配置
│   ├── zh.js             # 中文语言包
│   ├── en.js             # 英文语言包
│   └── ja.js             # 日文语言包
├── mac/                  # Mac风格界面
│   └── mode/             # 模式配置
├── mixins/               # 混入模块
│   ├── crud.js           # CRUD通用混入
│   └── index.js          # 混入入口
├── page/                 # 基础框架页面
│   ├── admin_user/       # 管理员用户管理
│   ├── applets_page/     # 小程序页面管理
│   ├── dev/              # 开发工具页面(可视化添加页面cli工具入口)
│   ├── index/            # 首页相关
│   │   ├── sidebar/      # 侧边栏组件
│   │   └── top/          # 顶部组件
│   ├── lock/             # 锁屏页面
│   ├── login/            # 登录页面
│   ├── menu/             # 菜单管理
│   ├── role/             # 角色管理
│   ├── share_img/        # 图片分享管理
│   ├── swiper/           # 轮播图管理
│   ├── sys_settings/     # 系统参数设置(只有超级管理员可见)
│   ├── user/             # 管理员信息管理
│   └── wel/              # 欢迎页面/首页
├── router/               # 路由配置
│   ├── avue-router.js    # Avue路由配置
│   ├── index.js          # 路由入口
│   ├── page/             # 基础路由
│   └── views/            # 业务路由(增加页面默认存放目录)
├── store/                # 状态管理
│   ├── getters.js        # 全局getters
│   ├── index.js          # store入口
│   └── modules/          # 模块化状态
│       ├── common.js     # 公共状态
│       ├── logs.js       # 日志状态
│       ├── tags.js        # 标签状态
│       └── user.js       # 用户状态
├── styles/               # 样式文件
│   ├── common.scss       # 公共样式
│   ├── element-ui.scss   # Element UI样式
│   ├── iconfont.scss     # 图标字体样式
│   ├── login.scss        # 登录页样式
│   ├── media.scss        # 媒体查询样式
│   ├── mixin.scss        # 样式混入
│   ├── normalize.scss    # 样式重置
│   ├── sidebar.scss      # 侧边栏样式
│   ├── tags.scss         # 标签样式
│   ├── theme/            # 主题样式
│   │   ├── beautiful.scss # 美丽主题
│   │   ├── dark.scss     # 暗黑主题
│   │   ├── index.scss    # 主题入口
│   │   ├── vip.scss      # VIP主题
│   │   └── white.scss    # 白色主题
│   ├── top.scss          # 顶部样式
│   └── variables.scss    # 样式变量
├── template/             # 模板文件
│   └── page/             # 页面模板
│       ├── api_template.js # API模板(未使用)
│       ├── template.js   # 配置模板
│       └── template.vue  # Vue模板
├── utils/                # 工具函数
│   ├── auth.js           # 认证工具
│   ├── captcha.js        # 验证码工具
│   ├── fileSaver.js      # 文件保存工具
│   ├── store.js          # 存储工具
│   ├── util.js           # 通用工具
│   ├── validate.js       # 验证工具
│   └── xlsx.full.min.js  # Excel处理工具
├── views/                # 业务页面
│   ├── article/          # 文章管理
│   ├── goods/            # 商品管理
│   └── util/             # 工具页面
├── App.vue               # 根组件
├── axios.js              # Axios配置
├── error.js              # 错误处理
├── main.js               # 应用入口
├── mockProdServer.js     # 生产环境Mock服务
└── permission.js         # 权限控制

快速开始

环境准备

开发环境要求

基础环境

  • Node.js: 版本 >= 16.0.0(推荐使用 LTS 版本)
  • 包管理器: npm/yarn/pnpm(推荐使用 pnpm,速度更快)
  • 浏览器: Chrome 87+, Firefox 78+, Safari 14+, Edge 88+

开发工具推荐

  • IDE: VS Code(推荐安装 Vue 3 插件)
  • 调试工具: Vue DevTools
  • API测试: Postman 或 Insomnia

项目安装与启动

项目获取

# 克隆项目(请替换为实际的项目地址)
git clone https://gitee.com/ylsg_1/avue3-template.git
cd 后台框架

安装依赖

# 安装依赖(推荐使用 cnpm)
cnpm install
# 或使用 npm
npm install
# 或使用 yarn
yarn install

启动开发服务器

# 启动开发服务器
cnpm dev
# 或
npm run dev
# 或
yarn dev

访问地址

http://localhost:5173

系统配置

全局配置管理

系统参数配置文件

️ 核心配置文件 项目的所有配置都集中在 src/config/settings.js 文件中,就像一个"控制面板",所有开关都在这里!

配置结构全览

// 主要配置项包括:
// - 系统基本信息(标题、描述、关键词)
// - 接口配置(加密开关、超时时间、基础URL)
// - 上传配置(文件大小限制、上传接口)
// - 认证配置(Token过期时间、认证头字段)
// - 菜单配置(图标、路径、权限字段)
// - 系统设置(侧边栏模式、主题、调试模式)
// - 登录配置(多种登录方式开关)
// - 国际化配置(多语言支持)
export default {
  // 系统标题
  title: 'YLSG后台管理系统',
  // 系统描述
  description: 'YLSG后台管理系统',
  // 系统关键词
  keywords: 'YLSG后台管理系统',
  // 是否启用网络异步路由
  asyncRoutes: true,
  // 接口配置
  api: {
    // 是否开启接口数据加密
    enableEncryption: false,
    // 加密密钥
    encryptionKey: 'HSTebjXJRNpnKGh7',
    // 接口超时时间(ms)
    timeout: 10000,
    // 开发环境接口地址
    devBaseUrl: 'https://avue3base.xxxyin.cn',
    // 是否开启mock数据
    enableMock: false,

  },

  // 上传配置
  upload: {
    // 图片上传接口
    imageUrl: '/base/upload_img',
    // 文件上传接口
    fileUrl: '/base/upload_file',
    // 上传大小限制(MB)
    maxSize: 10
  },


  // 系统Logo
  logo: "A",

  // 系统标识
  storeKey: 'key',

  // token配置
  tokenTime: 60,
  Authorization: 'Key',

  // http错误码白名单
  statusWhiteList: {
    '401': '认证失败,无法访问系统资源',
    '403': '当前操作没有权限',
    '404': '访问资源不存在',
    '500': '系统错误',
    '601': '操作失败',
    'default': '系统未知错误,请反馈给管理员'
  },

  // 首页配置
  fistPage: {
    name: "首页",
    path: "/"
  },

  // 菜单配置
  menu: {
    iconDefault: 'icon-caidan', // 默认菜单图标
    label: 'label',             // 菜单标题字段名
    path: 'path',              // 菜单路由路径字段名
    icon: 'icon',              // 菜单图标字段名
    children: 'children',      // 子菜单字段名
    query: 'query',            // 路由参数字段名
    href: 'href',              // 外链字段名
    meta: 'meta',              // 路由元信息字段名
    showIcon: true,            // 是否显示菜单图标
  },

  // 系统设置
  setting: {
    sidebar: 'vertical',      // 侧边栏模式,可选 vertical/horizontal/category
    tag: true,               // 是否显示标签页
    debug: false,             // 是否启用调试模式
    collapse: true,          // 是否允许折叠侧边栏
    search: true,            // 是否显示搜索框
    lock: true,              // 是否显示锁屏按钮
    color: true,             // 是否显示主题色设置
    screenshot: true,        // 是否显示截图按钮
    fullscren: true,         // 是否显示全屏按钮
    theme: true,             // 是否显示主题设置
    menu: true               // 是否显示菜单设置
  },

  // 登录配置
  login: {
    // 是否开启账号密码登录
    enableUserLogin: true,
    // 是否开启手机验证码登录
    enablePhoneLogin: false,
    // 是否开启人脸识别登录
    enableFaceLogin: false,
    // 是否开启第三方登录
    enableThirdLogin: false,
    // 是否开启图形验证码
    enableCaptcha: true
  },




  // 国际化配置
  i18n: {
    // 是否开启多语言
    enable: true,
    // 默认语言
    defaultLanguage: 'zh-CN',
    // 支持的语言列表
    languages: ['zh-CN', 'en-US']
  },
  
} 

Avue框架配置详解

Avue配置中心 Avue框架的配置位于 src/config/avue_cofig.js,这里定义了所有Avue组件的默认行为,配置参数说明可参考全局配置:

注意

以下为第三方云存储配置说明:

  • Avue 支持对接腾讯云 COS、七牛云、阿里云 OSS 等第三方云存储服务。
  • 配置项位于 src/config/avue_cofig.js,默认是注释状态。
  • 如需启用第三方云存储,请取消对应配置的注释,并填写相关参数。
  • 重要提示:一旦启用第三方云存储,原有的图片上传和文件上传接口将失效,务必确保云存储配置正确。
// 主要配置包括:
// - 组件尺寸设置
// - CRUD操作配置(增删改查按钮)
// - 表格样式配置(边框、斑马纹、对齐方式)
// - 表单配置(栅格间距、标签位置)
// - 对话框配置(拖拽、遮罩关闭)
// Avue全局配置对象
export const avueConfig = {
    // 组件默认尺寸,可选值:'medium' | 'small' | 'mini' | 'default'
    size: 'default',

    // axios实例,所有Avue的请求会走这里
    axios,

    // CRUD(增删改查)相关的全局默认配置
    crudOption: {
        // 是否显示编辑按钮
        editBtn: true,
        // 是否显示删除按钮
        delBtn: true,
        // 是否显示新增按钮
        addBtn: true,
        // 是否显示表格边框
        border: true,
        // 是否显示斑马纹
        stripe: true,
        // 是否显示序号列
        index: false,
        // 搜索表单菜单所占栅格数(24栅格制)
        searchMenuSpan: 8,
        // 表格内容对齐方式
        align: 'center',
        // 表头对齐方式
        headerAlign: 'center',
        // 是否显示操作栏
        menu: true,
        // 操作栏按钮类型,可选:'button' | 'text' | 'icon'
        menuType: 'text',
        // 表格高度,'auto'为自适应
        height: 'auto',
        // 表格栅格间距
        gutter: 30,
        // 自动计算表格高度时的偏移量
        calcHeight: 65,
        // 操作栏宽度
        menuWidth: 200,
        // 操作栏标题
        menuTitle: '可操作',
        // 操作栏内容对齐方式
        menuAlign: 'center',
        // 操作栏是否固定在右侧
        menuFixed: 'right',
        // 是否显示打印按钮
        printBtn: true,
        // 是否显示导出Excel按钮
        excelBtn: true,
        // 是否显示列设置按钮
        columnBtn: false,
        // 是否显示复制按钮
        copyBtn: false,
        // 对话框是否可拖拽
        dialogDrag: true,
        // 点击遮罩是否可关闭对话框
        dialogClickModal: true,
        // 搜索表单标签位置,可选:'left' | 'top'
        searchLabelPosition: 'left',
    },

    // 表单相关的全局默认配置
    formOption: {
        // 表单项之间的栅格间距
        gutter: 30,
        // 表单标签位置,可选:'left' | 'right' | 'top'
        labelPosition: 'top',
        // labelWidth: 110, // 可自定义标签宽度(如有需要可取消注释)
    },

    // 弹窗内容是否挂载到body(防止被父容器样式影响)
    appendToBody: true,
    // 模态框内容是否挂载到body
    modalAppendToBody: true,

    // 以下为第三方云存储配置(如需使用请取消注释并填写相关参数,注意,一旦取消注释第三方云存储,原来的图片上传,文件上传就会出错,非常重要)
    /*
    // 腾讯云COS配置
    cos: {
        SecretId: '',
        SecretKey: '',
        Bucket: '',
        Region: ''
    },
    // 七牛云配置
    qiniu: {
        AK: '',
        SK: '',
        scope: '',
        url: '',
        deadline: 1
    },
    // 阿里云OSS配置
    ali: {
        region: '',
        endpoint: '',
        accessKeyId: '',
        accessKeySecret: '',
        bucket: '',
    },
    */

    // 水印画布配置(用于表格/图片等水印功能)
    /*
    canvas: {
        text: 'avuejs.com',           // 水印文字
        fontFamily: 'microsoft yahei',// 字体
        color: "#999",                // 颜色
        fontSize: 16,                 // 字号
        opacity: 100,                 // 透明度
        bottom: 10,                   // 距离底部距离
        right: 10,                    // 距离右侧距离
        ratio: 1                      // 缩放比例
    }
    */
}

动态加载器配置

智能加载系统 动态加载器就像项目的"智能管家",根据实际需要加载相应的功能模块:

// 参考文件:src/config/loader.js 第1-20行
// 主要功能:
// - 按需加载组件和配置
// - 性能优化,减少初始加载时间
// - 智能缓存管理,避免重复加载
export function initConfig() {
  // (可选)保存配置到本地存储,可根据需要启用
  // setStore({ name: CONFIG_KEY, content: settings })

  // 如果启用API加密,则将加密/解密方法挂载到window全局对象
  if (settings.api.enableEncryption) {
    window.encryption = (data) => encryption(data)
    window.decryption = (data) => decryption(data)
  }

  // 设置页面标题
  if (settings.title) {
    document.title = settings.title;
  }

  // 设置meta description
  if (settings.description) {
    const metaDesc = document.querySelector('meta[name="description"]');
    if (metaDesc) {
      metaDesc.setAttribute('content', settings.description);
    }
  }

  // 设置meta keywords
  if (settings.keywords) {
    const metaKeywords = document.querySelector('meta[name="keywords"]');
    if (metaKeywords) {
      metaKeywords.setAttribute('content', settings.keywords);
    }
  }

  return settings
}

/**
 * 更新系统配置
 * @param {Object} newConfig - 新的配置对象
 * @returns {Object} 更新后的配置
 */
export function updateConfig(newConfig) {
  // 合并新配置到settings对象
  Object.assign(settings, newConfig)
  // 保存到本地存储
  setStore({ name: CONFIG_KEY, content: settings })
  return settings
}

/**
 * 重置系统配置为初始状态
 * @returns {Object} 重置后的配置
 */
export function resetConfig() {
  // 清空本地存储中的配置
  setStore({ name: CONFIG_KEY, content: null })
  // 重新初始化配置
  return initConfig()
}

核心功能

CRUD混入模块

原理与作用机制

CRUD混入模块是YLSG框架的"核心引擎",就像给每个页面组件装了一个"智能助手",让开发者从繁琐的增删改查代码中解放出来。它通过Vue混入机制实现代码复用,将通用的CRUD逻辑封装成可配置的模块。

混入模块的优势

  • 代码复用:一次编写,多处使用,告别"复制粘贴地狱"
  • 配置驱动:通过配置文件控制页面行为,无需修改核心逻辑
  • 权限集成:自动处理常见按钮权限显示,无需手动判断
  • 钩子灵活:提供丰富的生命周期钩子,事件钩子,满足个性化需求

动态配置加载机制

混入模块会在组件初始化时自动检测当前组件路径,然后动态加载对应的配置文件。就像"智能管家"一样,它会:

  • 自动识别组件所在目录结构
  • 动态导入 {module}.js 配置文件
  • 动态导入 api_{module}.js API文件
  • 根据用户权限设置按钮显示状态
  created() {
    const componentName = this.crudOption.name;
    // 动态检测组件所在目录
    const componentPath = this.$options.__file || '';
    // 尝试从组件路径中提取目录信息
    let componentDir = '';
    if (componentPath) {
      const srcIndex = componentPath.indexOf('src/');
      if (srcIndex !== -1) {
        const relativePath = componentPath.substring(srcIndex + 4); // 去掉 'src/'
        const lastSlashIndex = relativePath.lastIndexOf('/');
        if (lastSlashIndex !== -1) {
          componentDir = relativePath.substring(0, lastSlashIndex);
        }
      }
    }
    // 如果无法从路径获取,使用默认的page目录
    if (!componentDir) {
      componentDir = `page/${componentName}`;
    }
    // 构建文件路径 - 修正:确保包含/src前缀
    const optionPath = `src/${componentDir}/${componentName}.js`;
    const apiPath = `src/${componentDir}/api_${componentName}.js`;

    // 动态导入所有JS文件
    const modules = import.meta.glob('/src/**/*.js', { eager: false });
    // 加载配置文件
    const optionModulePath = `/${optionPath}`;

    if (modules[optionModulePath]) {
      modules[optionModulePath]().then((mode) => {
        this.option = mode.default ? mode.default(this) : mode(this);
        this.key = Math.random();
        // 配置加载完成后,如果API也已加载,则获取数据
        if (this.api && Object.keys(this.api).length > 0) {
          this.getList();
        }
      }).catch((error) => {
      });
    } 
    // 加载API文件
    const apiModulePath = `/${apiPath}`;
    if (modules[apiModulePath]) {
      modules[apiModulePath]().then((mode) => {
        this.api = mode;

        // API加载完成后,如果配置也已加载,则获取数据
        if (this.option && Object.keys(this.option).length > 0) {
          this.getList();
        }
      })
    } 
    // 自定义按钮权限钩子
    if (this.createdBefore) {
      this.createdBefore(this.BtnPermission, permission);
    }
    if (debug) console.log(`[页面][${componentName}] 按钮权限设置完成:`, this.BtnPermission);
  }

权限控制机制

混入模块内置了完整的权限控制逻辑,它会:

  • 根据用户权限自动显示/隐藏操作按钮
  • 支持菜单权限、按钮权限、路由权限一体化管理
  • 提供权限验证的钩子函数,支持自定义权限逻辑
// 按钮权限钩子函数
<template>
  <!-- 表格组件-->
  <avue-crud >
    <!-- 自定义操作按钮 -->
    <template #menu="scope">
      <el-button :type="menuType !== 'text' ? menuType : ''" :text="menuType == 'text'" icon="el-icon-view"  class="el-button--primary"
        @click="handle_see(scope.row, scope.index)" v-if="BtnPermission.article_see">
        自定义
      </el-button>
    </template>
  </avue-crud>
</template>

<script>
import crudMixin from '@/mixins/crud.js'

export default {
  name: 'article',
  mixins: [crudMixin({
    name: 'article'
  })],
  methods: {
    // 【自定义】事件处理
    handle_see(row, index) {
      console.log('自定义', row, index)
    },
    // 权限初始化
    createdBefore(BtnPermission, permission) {
    //createdBefore初始化后处理,这个钩子运行在页面生命周期初始化created中
    // 它可以在获取到BtnPermission,当然你还能做一些其他的处理,比如你希望页面初始化的时候处理一些数据
      
    // 自定义按钮权限配置
      if (permission) {
        BtnPermission.article_see = permission?.article_see;
      }
    },
    },
  }
</script>

数据封装处理

混入模块统一处理所有的数据操作,包括:

  • 数据过滤:自动清理表单中的临时字段(如 $cellEdit, $index 等)
  • 错误处理:统一的错误处理机制,避免重复代码
  • 响应处理:标准化的响应数据处理,支持自定义处理逻辑
// 公共方法:会递归过滤对象中所有以$开头的key,支持多级嵌套,
function filterDollarKeys(obj) {
  if (Array.isArray(obj)) {
    return obj.map(item => filterDollarKeys(item));
  } else if (obj && typeof obj === 'object') {
    const result = {};
    Object.keys(obj).forEach(key => {
      if (!key.startsWith('$')) {
        result[key] = filterDollarKeys(obj[key]);
      }
    });
    return result;
  }
  return obj;
}

事件处理机制

混入模块提供了完整的事件处理体系:

  • 生命周期钩子:支持 createdBefore, listBefore, addBefore 等钩子
  • 数据操作钩子:支持 addAfter, updateAfter, delAfter 等钩子
  • 自定义事件:支持自定义事件处理,满足特殊业务需求
created() {
    // ...动态载入配置
     // 自定义按钮权限钩子
    if (this.createdBefore) {
      this.createdBefore(this.BtnPermission, permission);
    }
},
methods: {
  /**
   * 获取数据列表
   */
  getList() {
    const callback = () => {
      // ...数据获取逻辑...
      apiMethod(data).then((res) => {
        // 列表获取后的回调处理
        if (this.listAfter) {
          data = this.listAfter(data);
        } else {
          this.$message.success("获取成功");
        }
        this.data = data;
      });
    };

    // 列表获取前的钩子
    if (this.listBefore) {
      this.listBefore();
    }
    callback();
  },

  /**
   * 保存新行数据
   */
  rowSave(row, done, loading) {
    const callback = () => {
      this.api[this.option.add || "add"](this.form).then((data) => {
        if (this.addAfter) {
          this.addAfter(data);
        } else {
          this.$message.success("新增成功");
        }
      });
    };

    if (this.addBefore) {
      this.addBefore();
    }
    callback();
  },

  /**
   * 更新行数据
   */
  rowUpdate(row, index, done, loading) {
    const callback = () => {
      this.api[this.option.update || "update"](this.form).then((data) => {
        if (this.updateAfter) {
          this.updateAfter(data);
        } else {
          this.$message.success("更新成功");
        }
      });
    };

    if (this.updateBefore) {
      this.updateBefore();
    }
    callback();
  },

  /**
   * 删除行数据
   */
  rowDel(row, index) {
    const callback = () => {
      this.api[this.option.del || "del"]({ id: row.id }).then((data) => {
        if (this.delAfter) {
          this.delAfter(data, row, index);
        } else {
          this.$message.success("删除成功");
        }
      });
    };

    if (this.delBefore) {
      this.delBefore();
      callback();
    }
  },

  /**
   * 搜索条件变化处理
   */
  searchChange(params, done) {
    // 搜索前钩子处理
    if (this.searchBefore) {
      const processedParams = this.searchBefore(params);
      if (processedParams === false) return;
      params = processedParams || params;
    }
    this.getList();
  }
}

灵活钩子函数

混入模块提供了丰富的钩子函数,就像给开发者提供了"自定义工具箱"️:

生命周期钩子

  • createdBefore(BtnPermission, permission) - 组件初始化后执行
  • listBefore() - 获取列表数据前执行
  • listAfter(data) - 获取列表数据后执行

数据操作钩子

  • addBefore() - 新增数据前执行
  • addAfter(data) - 新增数据后执行
  • updateBefore() - 更新数据前执行
  • updateAfter(data) - 更新数据后执行
  • delBefore() - 删除数据前执行
  • delAfter(data, row, index) - 删除数据后执行

搜索和导入导出钩子

  • searchBefore(params) - 搜索前执行
  • beforeImportData() - 导入前执行(必须返回表单配置)
  • beforeExportData(params) - 导出前执行
  • afterExportData(res, error) - 导出后执行

下载模板钩子

  • beforeDownloadTemplate()- 下载模板前
  • afterDownloadTemplate(res, error)- 下载模板后

钩子函数返回值规则

  • 返回 false:阻止后续操作执行
  • 返回其他值或无返回值:继续执行后续操作

钩子实际使用示例:

// 参考文件:src/page/user/user.vue 第20-40行
// 主要功能:用户管理页面的钩子函数示例
export default {
  mixins: [crud({ name: 'user' })],
  methods: {
    // 新增前:添加默认值
    addBefore() {
      this.form.create_time = this.$dayjs().format('YYYY-MM-DD HH:mm:ss')
      this.form.status = 1 // 默认启用状态
    },
    
    // 更新前:添加更新时间
    updateBefore() {
      this.form.update_time = this.$dayjs().format('YYYY-MM-DD HH:mm:ss')
    },
    
    // 搜索前:预处理搜索参数
    searchBefore(params) {
      if (params.username) {
        params.username = params.username.trim()
      }
      return params
    }
  }
}

小技巧

  • 钩子函数应该保持简洁,复杂的业务逻辑建议封装成独立方法
  • 充分利用钩子函数的返回值控制流程,避免不必要的API调用
  • 在钩子函数中添加必要的日志记录,便于问题排查

用户认证与权限管理

Token管理策略

Token管理就像"数字身份证",系统采用了一套完整的Token生命周期管理策略:

1. Token生成与存储

  • 自动生成:登录成功后自动获取JWT Token
  • 安全存储:Token存储在本地存储中
  • 过期时间:可灵活配置Token过期时间,默认60分钟

2. Token自动刷新

  • 智能刷新:Token即将过期时自动刷新
  • 无缝体验:用户无感知的Token更新
  • 失败处理:刷新失败时自动跳转登录页

3. Token验证机制

  • 请求拦截:每个API请求头自动携带Token(这次放到了headers中)
  • 响应拦截:自动处理Token过期情况
  • 权限验证:结合Token进行权限验证

Token安全注意事项

  • Token存储在本地存储中,建议在生产环境启用HTTPS
  • Token过期时间不宜设置过长,建议30-60分钟
  • 支持Token黑名单机制,登出时自动加入黑名单

用户信息管理

用户信息管理就像"个人档案室",系统提供了完整的用户信息管理功能:

用户信息存储

  • Vuex状态管理:用户信息存储在Vuex中,全局共享
  • 本地缓存:关键信息本地缓存,提升访问速度
  • 实时同步:用户信息变更时实时更新

用户信息获取

  • 自动获取:登录成功后自动获取用户详细信息
  • 权限信息:同时获取用户权限列表
  • 角色信息:获取用户角色和权限范围
 getMemberInfo({ commit }) {
      return new Promise((resolve, reject) => {
        getMemberInfo().then((res) => {
          const data = res;
          //用户信息存储
          commit('SET_USERIFNO', data.userInfo);
          commit('SET_ROLES', data.roles);
          commit('SET_PERMISSION', data.permission)
          resolve(data);
        }).catch(err => {
          reject(err);
        })
      })

用户信息使用示例

// 在组件中获取用户信息
export default {
  computed: {
    userInfo() {
      return this.$store.state.user.userInfo
    },
    userPermissions() {
      return this.$store.state.user.permission
    }
  },
  
  methods: {
    // 检查用户权限
    hasPermission(permission) {
      return this.userPermissions[permission] || false
    }
  }
}

全局缓存参数详解与使用

src/store/modules/user.js 缓存参数说明

参数名用途存入时机可用场景使用方法
userInfo用户基本信息登录成功后显示用户信息、权限判断this.$store.state.user.userInfo
permission用户权限列表获取用户信息后按钮权限控制this.$store.state.user.permission
roles用户角色列表获取用户信息后角色权限判断this.$store.state.user.roles
menuId菜单ID映射获取菜单后菜单权限控制this.$store.state.user.menuId
menu用户菜单列表登录后获取侧边栏菜单显示this.$store.state.user.menu
menuAll所有菜单列表获取菜单后菜单管理功能this.$store.state.user.menuAll
token访问令牌登录成功后API请求认证this.$store.state.user.token
refreshToken刷新令牌登录成功后Token刷新this.$store.state.user.refreshToken

使用示例

// 在组件中使用
export default {
  computed: {
    userInfo() {
      return this.$store.state.user.userInfo
    },
    hasEditPermission() {
      return this.$store.state.user.permission['user_edit']
    }
  },
  
  methods: {
    checkPermission(permission) {
      return this.$store.state.user.permission[permission]
    }
  }
}

权限管理体系

YLSG后台管理系统的权限体系就像"数字门禁系统",通过多层权限控制确保系统安全。它采用路由权限、菜单权限、按钮权限三位一体的控制机制,配合角色管理和动态菜单配置,构建了完整的权限管理体系。

路由权限控制

路由权限控制就像"交通管制",通过全局路由守卫确保用户只能访问有权限的页面:

运行逻辑:

  1. 全局前置守卫:在 src/permission.js 中配置路由守卫
  2. Token验证:检查用户是否已登录,未登录跳转登录页
  3. 用户信息获取:登录后自动获取用户角色和权限信息(最新后端接口全放在了获取用户信息中)
  4. 路由匹配:根据用户权限过滤可访问的路由
  5. 动态路由:支持异步路由加载,按需生成路由配置

参考文件:src/permission.js 第1-131行

核心流程:

// 路由守卫核心逻辑
router.beforeEach((to, from, next) => {
  // 1. 检查Token
  if (getToken()) {
    // 2. 获取用户信息
    if (store.getters.roles.length === 0) {
      store.dispatch('getMemberInfo').then(() => {
        next({ ...to, replace: true })
      })
    } else {
      // 3. 权限验证通过,允许访问
      next()
    }
  } else {
    // 4. 无Token,跳转登录页
    next('/login')
  }
})

路由权限特点

  • 支持异步路由加载,提升系统性能
  • 自动处理Token过期情况
  • 支持外部链接和标签页管理
  • 框架已集成进度条显示,提升用户体验

菜单权限控制

菜单权限控制就像"菜单管家",通过远程菜单配置限制用户可见的菜单项:

运行逻辑:

  1. 远程菜单获取:从后端获取用户有权限的菜单列表
  2. 菜单数据过滤:根据用户权限过滤菜单项
  3. 动态菜单渲染:只显示用户有权限的菜单
  4. 菜单配置适配:通过 menu 配置 适配不同后端菜单结构

菜单权限重要说明

  • 远程菜单:通过后端接口获取,可以精确控制用户菜单权限
  • 本地菜单:无法控制权限,仅用于开发调试

按钮权限管理

按钮权限管理就像"操作开关",通过权限标识控制页面按钮的显示和功能:

运行逻辑:

  1. 权限标识获取:从用户权限列表中获取按钮权限标识
  2. 按钮权限设置:根据权限标识设置按钮显示状态
  3. 动态权限控制:支持自定义按钮权限钩子
  4. 权限回退机制:当启用本地菜单时,默认显示所有按钮

页面权限标识基础规则

  • 页面名_edit:编辑按钮权限
  • 页面名_del:删除按钮权限
  • 页面名_add:新增按钮权限
  • 页面名_import:导入按钮权限
  • 页面名_export:导出按钮权限
  • 页面名_down:下载模板按钮权限

按钮权限特点

  • 支持自定义权限钩子,灵活扩展权限控制
  • 权限标识采用"页面名_操作"的命名规则
  • 支持权限回退,本地菜单模式下默认显示所有按钮
  • 实时权限验证,确保操作安全性

角色管理功能

角色管理功能就像"权限分配中心",超级管理员可以在系统管理菜单组下的角色管理中,在操作栏中点击权限设置,勾选菜单权限即可。

操作流程:

  1. 进入系统管理 → 角色管理
  2. 在角色列表的操作栏中点击"权限设置"
  3. 在弹出的权限设置对话框中勾选相应的菜单权限
  4. 保存设置,权限立即生效

权限设置界面:

[此处需附图:角色权限设置界面,显示菜单权限勾选界面]

角色管理说明

  • 只有超级管理员可以管理角色权限
  • 权限设置实时生效,无需重启系统
  • 支持批量权限设置,提高管理效率

动态菜单配置

动态菜单配置就像"菜单开关",通过全局配置控制菜单的加载方式:

配置说明: 在 src/config/settings.js 中通过 asyncRoutes 配置控制菜单加载方式:

// 是否启用网络异步路由
asyncRoutes: true,  // true: 远程菜单,false: 本地菜单

两种模式对比:

配置项本地菜单模式远程菜单模式
asyncRoutes: false启用禁用
asyncRoutes: true禁用启用
权限控制无法控制权限精确权限控制
菜单来源本地路由配置后端接口返回
适用场景开发调试生产环境

菜单模式重要提醒

  • 本地菜单:无法控制权限,仅用于开发调试
  • 远程菜单:可以精确控制用户菜单权限,推荐生产环境使用
  • 切换菜单模式需要重启应用才能生效

分店权限管理

分店权限管理机制已做出重要调整,现行逻辑如下:

1. 分店与管理员账号绑定

  • 分店表不再单独存储账号密码,分店管理员账号直接与系统管理员表(ylsg_sys_member)绑定。
  • 分店管理员的超级管理员角色ID固定为2,且管理员表中新增 branch_id 字段用于标识所属分店。
  • 新增分店时,通过一个接口同时创建分店信息和分店管理员账号(含账号、密码),分别在分店表和管理员表建立记录,并自动建立关联关系。

2. 分店管理员账号保护

  • 当全局配置 settings.js 中 enableBranchStore 设置为 true 时,角色ID为2的分店管理员账号不可被删除,保障分店管理的完整性。

3. 分店管理员登录与信息获取

  • 分店管理员登录后台后,/member/get_member_info 接口会直接返回其对应的分店信息,便于前端根据分店上下文进行业务处理。

4. 分店权限配置与角色管理

  • 分店代码无需独立分包,所有分店权限均可在总后台通过角色权限配置灵活分配。
  • 分店可在自身权限范围内独立设置分店下属角色,分店自定义角色的权限上限受总后台为该分店分配的权限范围限制,实现权限下放与隔离。

5. 分店与管理员禁用逻辑

  • 分店被禁用后,所有属于该分店的管理员账号将无法登录系统,实现分店级别的统一禁用。
  • 若仅禁用某个分店管理员账号,则仅该账号无法登录,其他同分店管理员账号不受影响。

分店权限管理小结

  • 分店与管理员强绑定,权限分配灵活,支持分店独立角色管理
  • 分店禁用与管理员禁用互不干扰,保障系统安全与灵活性
  • 相关配置与逻辑详见 settings.js 及后台接口文档

API接口设计

Axios配置与拦截器

Axios配置就像"HTTP请求管家",提供了完整的请求生命周期管理,包括安全防护、错误处理、调试支持等功能。

基础配置

  • baseURL:根据Mock模式动态设置,Mock模式下为空,否则为 /admin
  • timeout:请求默认超时时间10秒
  • withCredentials:允许跨域请求携带cookie

请求拦截器

  • 时间戳防重放: 每个请求自动添加当前时间戳,POST/PUT请求添加到请求体,GET请求添加到URL参数
  • Token自动注入: 自动从localStorage获取Token并添加到请求头,可通过 isToken: false 禁用
  • 数据清洗: 自动过滤空值(null、undefined、空字符串、空数组、空对象等),只对非FormData类型请求体处理
  • 数据加密: 通过 settings.api.enableEncryption 控制,使用全局 window.encryption 方法加密
  • 防重复提交: 1秒内相同URL和数据的POST/PUT请求会被拦截,可通过 repeatSubmit: false 禁用

响应拦截器

  • 二进制数据处理: 文件下载等二进制数据直接返回原始数据,不进行业务逻辑处理
  • 业务状态码处理:
    • 200: 成功状态,上传和选择接口返回原始response,其他接口返回 res.data.datas
    • 400: 业务错误,显示错误信息
    • 555: 系统错误,显示错误信息
    • 777: 警告信息,显示警告提示
    • 999: Token过期,弹出重新登录确认框

错误处理

  • HTTP状态码白名单: 401认证失败、403权限不足、404资源不存在、500系统错误、601操作失败,在全局配置中可修改。
  • Token过期处理: 使用全局标志防止重复弹窗,用户确认后执行登出并跳转首页
  • 错误提示策略: 500错误显示error类型消息,其他错误显示warning类型消息

调试功能

  • 请求数据调试: 通过全局配置 settings.setting.debug 控制,GET请求打印params,其他请求打印data
  • 响应数据调试: 打印完整的响应数据结构

接口使用方式

// 先引入
import request from '@/axios';

// 基础使用示例
export const getUsers = (params) => {
  return request({
    url: '/api/users',
    method: 'get',
    params
  })
}

// 创建用户
export const createUser = (data) => {
  return request({
    url: '/api/users',
    method: 'post',
    data
  })
}

// 禁用Token
export const login = (data) => {
  return request({
    url: '/api/login',
    method: 'post',
    data,
    headers: {
      isToken: false
    }
  })
}

// (禁用防重复提交)
export const submitForm = (data) => {
  return request({
    url: '/api/submit',
    method: 'post',
    data,
    headers: {
      repeatSubmit: false
    }
  })
}
// 页面使用示例
// 以获取用户列表为例,页面中可这样调用API方法:
// curd混入默认已经全部引入,直接可以用this.api.方法名调用
import { getUsers, createUser } from '@/views/user/api_user' // 假设API文件路径

export default {
  data() {
    return {
      userList: [],
      loading: false,
      form: {
        name: '',
        age: ''
      }
    }
  },
  methods: {
    // 获取用户列表
    fetchUsers() {
      this.loading = true
      getUsers({ page: 1, size: 10 }).then(res => {
        this.userList = res.data.list
      }).finally(() => {
        this.loading = false
      })
    },
    // 新建用户
    handleCreate() {
      createUser(this.form).then(res => {
        this.$message.success('创建成功')
        this.fetchUsers()
      })
    }
  },
  mounted() {
    this.fetchUsers()
  }
}

全局配置项说明:

  • api.enableEncryption: 是否启用数据加密
  • api.enableMock: 是否启用Mock模式
  • api.timeout: 请求超时时间
  • setting.debug: 是否启用调试模式
  • Authorization: Token字段名
  • statusWhiteList: HTTP状态码错误信息映射

这个axios配置提供了完整的HTTP请求生命周期管理,包括安全防护、错误处理、调试支持等功能,是一个企业级的HTTP客户端配置。

框架基础接口

登录接口

接口描述:用户登录验证 接口地址:/login/login
请求方式:POST
请求参数:

参数名示例值类型说明
usernameadminstring用户名
password123string密码
codebT26string验证码
requeTime1754117616number时间戳验证条件

返回示例:

{
  "code": 200,
  "datas": {
    "id": 1,
    "username": "admin",
    "nickname": "超级管理员",
    "avatar": "http://avue3base.xxxyin.cn/uploads/base/admin.jpg",
    "state": 1,
    "role_id": 1,
    "type": 1,
    "key": "3705e45463f667ab7f3fbe182779e458",
    "key_time": 1754117618,
    "add_time": 0,
    "update_time": 1649231810,
    "last_login_time": 1754117618,
    "last_login_ip": "183.226.112.242",
    "p_id": 0,
    "client_id": ""
  }
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datas.idnumber用户ID
datas.usernamestring用户名
datas.nicknamestring用户昵称
datas.avatarstring用户头像URL
datas.statenumber用户状态
datas.role_idnumber角色ID
datas.typenumber用户类型
datas.keystring登录凭证token
datas.key_timenumbertoken生成时间
datas.last_login_timenumber最后登录时间
datas.last_login_ipstring最后登录IP

获取用户信息接口

接口描述:获取当前登录用户信息 接口地址:/member/get_member_info
请求方式:POST
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": {
    "userInfo": {
      "id": 1,
      "username": "admin",
      "password": "cd33c6223e01d512b6462f00c40fdf02",
      "nickname": "超级管理员",
      "avatar": "http://avue3base.xxxyin.cn/uploads/base/admin.jpg",
      "state": 1,
      "role_id": 1,
      "type": 1,
      "key": "3705e45463f667ab7f3fbe182779e458",
      "key_time": "2025-08-02 14:53:38",
      "add_time": "",
      "update_time": "2022-04-06 15:56:50",
      "last_login_time": "2025-08-02 14:53:38",
      "last_login_ip": "183.226.112.242",
      "p_id": 0,
      "client_id": "",
      "role_weight": 1
    },
    "roles": {
      "role_id": 1,
      "role_name": "超级管理员",
      "weight": 1
    },
    "permission": [
      "index_import",
      "index_export",
      "index_del",
      "index_edit",
      "index_add",
      "MenuManagement_import",
      "MenuManagement_export",
      "MenuManagement_del",
      "MenuManagement_edit",
      "MenuManagement_add",
      "role_import",
      "role_export",
      "role_del",
      "role_edit",
      "role_add",
      "admin_user_import",
      "admin_user_export",
      "admin_user_del",
      "admin_user_edit",
      "admin_user_add",
      "applets_page_del",
      "applets_page_detail",
      "applets_page_edit",
      "applets_page_add",
      "share_img_del",
      "share_img_detail",
      "share_img_edit",
      "share_img_add",
      "swiper_del",
      "swiper_detail",
      "swiper_edit",
      "swiper_add"
    ]
  }
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datas.userInfoobject用户信息对象
datas.userInfo.idnumber用户ID
datas.userInfo.usernamestring用户名
datas.userInfo.nicknamestring用户昵称
datas.userInfo.avatarstring用户头像
datas.userInfo.statenumber用户状态
datas.userInfo.role_idnumber角色ID
datas.userInfo.role_weightnumber角色权重
datas.rolesobject角色信息
datas.roles.role_idnumber角色ID
datas.roles.role_namestring角色名称
datas.roles.weightnumber角色权重
datas.permissionarray权限列表

菜单获取接口

接口描述:获取用户菜单权限信息 接口地址:/member/get_menu_role_info
请求方式:POST
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": [
    {
      "id": 1,
      "p_id": 0,
      "sort": 0,
      "label": "首页",
      "icon": "fa-solid fa-desktop",
      "is_show": 0,
      "is_top": 2,
      "query": "",
      "path": "/wel",
      "href": "",
      "type": 1,
      "meta": {
        "title": "首页",
        "icon": "fa-solid fa-desktop"
      },
      "add_time": 1752054402,
      "update_time": 1753452378,
      "hidden": 0,
      "children": [
        {
          "id": 2,
          "p_id": 1,
          "sort": 0,
          "label": "首页",
          "icon": "fa-solid fa-desktop",
          "is_show": 0,
          "is_top": 2,
          "query": "",
          "path": "index",
          "href": "",
          "type": 2,
          "meta": {
            "title": "首页",
            "icon": "fa-solid fa-desktop"
          },
          "add_time": 1752054402,
          "update_time": 1753452508,
          "hidden": 0,
          "children": [
            {
              "id": 11,
              "p_id": 2,
              "sort": 0,
              "label": "首页导入数据",
              "icon": "",
              "is_show": 0,
              "is_top": 2,
              "query": "",
              "path": "index_import",
              "href": "",
              "type": 3,
              "meta": {
                "title": "首页导入数据",
                "icon": "",
                "i18n": "i18n"
              },
              "add_time": 1752054402,
              "update_time": 1752054402,
              "hidden": 0,
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasarray菜单列表
datas[].idnumber菜单ID
datas[].p_idnumber父级菜单ID
datas[].sortnumber排序值
datas[].labelstring菜单标签
datas[].iconstring菜单图标
datas[].is_shownumber是否显示
datas[].is_topnumber是否置顶
datas[].pathstring路由路径
datas[].typenumber菜单类型
datas[].metaobject菜单元信息
datas[].childrenarray子菜单列表

登出接口

接口描述:用户退出登录 接口地址:/login/logout
请求方式:POST
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

Token刷新接口

接口描述:刷新用户登录凭证 接口地址:/member/refresh
请求方式:POST
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "a97dd07246eb37d85ef61f917e3e7ae2"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring新的token凭证

获取备案信息接口

接口描述:获取系统底部备案信息 接口地址:/login/record_info
请求方式:POST
请求参数:无

返回示例:

{
  "code": 200,
  "datas": {
    "record_number": "",
    "record_url": "https://beian.miit.gov.cn"
  }
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datas.record_numberstring备案号
datas.record_urlstring备案链接

获取菜单列表接口

接口描述:获取菜单列表数据 接口地址:/menu/get_menu_list
请求方式:GET
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": [
    {
      "id": 1,
      "p_id": 0,
      "sort": 0,
      "label": "首页",
      "icon": "fa-solid fa-desktop",
      "is_show": 0,
      "is_top": 2,
      "query": "",
      "path": "/wel",
      "href": "",
      "type": 1,
      "meta": {
        "title": "首页",
        "icon": "fa-solid fa-desktop"
      },
      "add_time": "2025-07-09 17:46:42",
      "update_time": "2025-07-25 22:06:18",
      "children": [
        {
          "id": 2,
          "p_id": 1,
          "sort": 0,
          "label": "首页",
          "icon": "fa-solid fa-desktop",
          "is_show": 0,
          "is_top": 2,
          "query": "",
          "path": "index",
          "href": "",
          "type": 2,
          "meta": {
            "title": "首页",
            "icon": "fa-solid fa-desktop"
          },
          "add_time": "2025-07-09 17:46:42",
          "update_time": "2025-07-25 22:08:28",
          "children": [
            {
              "id": 11,
              "p_id": 2,
              "sort": 0,
              "label": "首页导入数据",
              "icon": "",
              "is_show": 0,
              "is_top": 2,
              "query": "",
              "path": "index_import",
              "href": "",
              "type": 3,
              "meta": {
                "title": "首页导入数据",
                "icon": "",
                "i18n": "i18n"
              },
              "add_time": "2025-07-09 17:46:42",
              "update_time": "2025-07-09 17:46:42",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasarray菜单列表数据

批量添加菜单接口

接口描述:批量添加菜单数据 接口地址:/menu/all_add
请求方式:POST
请求参数:

参数名示例值类型说明
json_all菜单json字符串string菜单json字符串,系统会自行处理view中的路由
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

获取菜单详情接口

接口描述:获取单个菜单详情信息 接口地址:/menu/get_menu_info
请求方式:GET
请求参数:

参数名示例值类型说明
id1number菜单ID
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": {
    "id": 6,
    "p_id": 0,
    "sort": 1,
    "label": "运营管理",
    "icon": "",
    "is_show": 0,
    "is_top": 2,
    "query": "",
    "path": "/operation",
    "href": "",
    "type": 1,
    "meta": {
      "title": "运营管理"
    },
    "add_time": "2025-08-02 15:39:34",
    "update_time": "2025-08-02 15:39:34"
  }
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasobject菜单详情数据

更新菜单接口

接口描述:更新菜单信息 接口地址:/menu/edit
请求方式:POST
请求参数:

参数名示例值类型说明
id1number菜单ID
label系统管理string菜单标签
meta{"title":"系统管理"}string菜单元信息JSON字符串
type1string菜单类型
sort3number排序值
path/systemstring路由路径
p_id0number父级菜单ID
is_show0number是否显示
is_top2number是否置顶
requeTime1754120718number时间戳验证条件
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

创建菜单接口

接口描述:创建新菜单 接口地址:/menu/add
请求方式:POST
请求参数:

参数名示例值类型说明
labelceshistring菜单标签
meta{"title":"测试","icon":"fa-solid fa-store"}string菜单元信息JSON字符串
type2string菜单类型
sort0number排序值
pathceshistring路由路径
queryceshistring查询参数
p_id6number父级菜单ID
is_show0number是否显示
is_top2number是否置顶
requeTime1754121306number时间戳验证条件
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

删除菜单接口

接口描述:删除指定菜单 接口地址:/menu/del
请求方式:POST
请求参数:

参数名示例值类型说明
id55number菜单ID
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

清空菜单接口

接口描述:清空所有菜单数据 接口地址:/menu/clear_menu
请求方式:GET
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "菜单已清空,自增ID已重置"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

获取角色列表接口

接口描述:获取角色列表(分页) 接口地址:/role/get_role_list
请求方式:POST
请求参数:

参数名示例值类型说明
pageNum1number页码
pageSize10number每页数量
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": {
    "num": 4,
    "data": [
      {
        "id": 1,
        "role_name": "超级管理员",
        "state": 1,
        "sort": 0,
        "roleval": "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54",
        "cmark": "最高权限管理员",
        "add_time": 1598587433,
        "update_time": 1753869363,
        "weight": 1
      }
    ]
  }
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datas.numnumber总数量
datas.dataarray角色列表数据
datas.data.idnumber角色ID
datas.data.role_namestring角色名称
datas.data.statenumber角色状态
datas.data.sortnumber排序值
datas.data.rolevalstring角色权限值
datas.data.cmarkstring角色备注
datas.data.weightnumber角色权重

获取所有角色接口

接口描述:获取所有角色数据 接口地址:/role/show_role_list
请求方式:GET
请求参数:

参数名示例值类型说明
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": [
    {
      "id": 1,
      "role_name": "超级管理员",
      "state": 1,
      "weight": 1
    }
  ]
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasarray角色列表数据

删除角色接口

接口描述:删除指定角色 接口地址:/role/del
请求方式:POST
请求参数:

参数名示例值类型说明
id55number角色ID
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

新增角色接口

接口描述:创建新角色 接口地址:/role/add
请求方式:POST
请求参数:

参数名示例值类型说明
role_name新框架string角色名称
cmark测试新框架string角色备注
weight1number角色权重
state1number角色状态
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

更新角色接口

接口描述:更新角色信息 接口地址:/role/edit
请求方式:POST
请求参数:

参数名示例值类型说明
id1number角色ID
role_name新框架string角色名称
cmark测试新框架string角色备注
weight1number角色权重
state1number角色状态
token3705e45463f667ab7f3fbe182779e458stringtoken凭证,放在headers中

返回示例:

{
  "code": 200,
  "datas": "操作成功"
}

返回参数说明::

参数名类型说明
codenumber状态码,200表示成功
datasstring操作结果信息

基础组件

组件使用指南

框架提供了一套完整的基础组件库,涵盖了常见的页面布局和交互需求。这些组件都经过精心设计,支持主题定制和响应式布局。

容器组件系统

basic-container - 页面容器组件

组件描述:提供标准化的页面容器布局,自动处理内边距和背景样式。

Props:

参数名类型默认值说明
paddingString'20px'内边距
backgroundString'#fff'背景色
heightString'auto'容器高度

使用示例:

<template>
  <basic-container>
    <el-card>
      <div>页面内容</div>
    </el-card>
  </basic-container>
</template>

最佳实践

建议在页面根元素使用 basic-container,可以确保页面布局的一致性和美观性。

basic-block - 块级组件

组件描述:提供可折叠的内容块容器,支持标题显示和折叠功能。

Props:

参数名类型默认值说明
titleString-块标题
collapsibleBooleanfalse是否可折叠
collapsedBooleanfalse是否默认折叠

使用示例:

<template>
  <basic-block title="数据统计" :collapsible="true">
    <div>统计内容</div>
  </basic-block>
</template>

块级组件功能

basic-video - 视频组件

组件描述:基于 Video.js 封装的视频播放组件,支持多种视频格式和自定义控制。

Props:

参数名类型默认值说明
srcString-视频源地址
widthString/Number'100%'视频宽度
heightString/Number'300px'视频高度
controlsBooleantrue是否显示控制条
autoplayBooleanfalse是否自动播放
loopBooleanfalse是否循环播放

使用示例:

<template>
  <basic-video 
    :src="videoUrl" 
    :width="800"
    :height="450"
    :controls="true"
  />
</template>

<script>
export default {
  data() {
    return {
      videoUrl: 'https://example.com/video.mp4'
    }
  }
}
</script>

浏览器兼容性

视频组件支持 MP4、WebM、Ogg 等主流格式,建议提供多种格式以确保兼容性。

视频组件配置

自定义视频配置

// 在 src/components/basic-video/plugin.js 中配置
export default {
  // 视频播放器配置
  videojs: {
    controls: true,
    fluid: true,
    responsive: true,
    preload: 'metadata'
  },
  
  // 自定义控制按钮
  customControls: {
    play: true,
    pause: true,
    fullscreen: true,
    volume: true
  }
}

内嵌框架组件

iframe - 内嵌框架组件

组件描述:提供安全的内嵌框架功能,支持跨域页面嵌入和通信。

Props:

参数名类型默认值说明
srcString-源地址
widthString/Number'100%'框架宽度
heightString/Number'400px'框架高度
frameborderString'0'边框样式
allowfullscreenBooleanfalse是否允许全屏

使用示例:

<template>
  <iframe 
    :src="externalUrl"
    :width="800"
    :height="600"
    frameborder="0"
    allowfullscreen
  />
</template>

安全提醒

使用 iframe 组件时,请确保嵌入的页面来源可信,避免 XSS 攻击风险。

用户信息组件

Userinfo - 用户信息展示组件

组件描述:专门用于展示用户头像、昵称和手机号的信息容器组件。

Props:

参数名类型必填说明
avatarString是用户头像URL
nicknameString是用户昵称
phoneString是用户手机号

组件功能:

  • 显示用户头像(48x48px 圆形头像)
  • 显示用户昵称(15px 字体,加粗样式)
  • 显示用户手机号(12px 字体,灰色样式)

样式预览:

使用示例:

<template>
  <Userinfo 
    avatar="https://example.com/avatar.jpg"
    nickname="张三"
    phone="138****8888"
  />
</template>

<script>
import Userinfo from '@/components/Userinfo/Userinfo.vue'

export default {
  components: {
    Userinfo
  }
}
</script>

样式定制

组件支持通过 CSS 变量自定义样式,可在全局样式中覆盖默认样式。

文件管理组件

FileManagerDialog - 文件管理对话框组件

组件描述:提供完整的文件上传、预览、删除功能,支持多种文件类型和批量操作。

Props:

参数名类型默认值说明
fileListArray[]文件列表
acceptString'*'接受的文件类型
maxSizeNumber10最大文件大小(MB)
multipleBooleanfalse是否支持多选
showPreviewBooleantrue是否显示预览

Events:

事件名参数说明
uploadfile文件上传事件
deletefile文件删除事件
previewfile文件预览事件

使用示例:

<template>
  <file-manager 
    :file-list="files"
    accept=".jpg,.png,.pdf"
    :max-size="5"
    :multiple="true"
    @upload="handleUpload"
    @delete="handleDelete"
    @preview="handlePreview"
  />
</template>

<script>
export default {
  data() {
    return {
      files: []
    }
  },
  methods: {
    handleUpload(file) {
      console.log('上传文件:', file)
    },
    handleDelete(file) {
      console.log('删除文件:', file)
    },
    handlePreview(file) {
      console.log('预览文件:', file)
    }
  }
}
</script>
文件管理组件源码实现
// src/components/file-manager/file.js
export default {
  // 文件上传处理
  uploadFile(file) {
    const formData = new FormData()
    formData.append('file', file)
    return this.$http.post('/upload', formData)
  },
  
  // 文件预览处理
  previewFile(file) {
    if (file.type.startsWith('image/')) {
      return this.previewImage(file)
    }
    return this.previewDocument(file)
  }
}

富文本编辑器

avue-plugin-ueditor - 富文本编辑器组件

组件描述:基于 UEditor编辑器 封装的富文本编辑组件,支持图片/视频上传和复制粘贴功能。

配置说明:

  • 支持富文本编辑和格式化
  • 支持图片/视频上传功能
  • 支持复制粘贴内容
  • 可自定义工具栏配置

使用示例:

<template>
  <avue-form :option="option" v-model="form">
    <template #content>
      <avue-ueditor 
        v-model="form.content"
        :config="editorConfig"
        @ready="onEditorReady"
      />
    </template>
  </avue-form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        content: ''
      },
      option: {
        column: [
          {
            label: '内容',
            prop: 'content',
            type: 'ueditor'
          }
        ]
      },
      editorConfig: {
        // 编辑器配置
        toolbars: [
          'fullscreen', 'source', '|', 'undo', 'redo', '|',
          'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
          'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
          'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
          'directionalityltr', 'directionalityrtl', 'indent', '|',
          'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
          'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
          'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',
          'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',
          'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
          'print', 'preview', 'searchreplace', 'drafts', 'help'
        ],
        initialFrameHeight: 400,
        autoHeightEnabled: false
      }
    }
  },
  methods: {
    onEditorReady(editor) {
      console.log('编辑器初始化完成:', editor)
    }
  }
}
</script>

编辑器优化建议

  1. 建议设置合适的 initialFrameHeight 避免页面跳动
  2. 可根据业务需求自定义工具栏按钮
  3. 注意图片上传路径配置,确保上传功能正常

错误页面组件

错误页面组件系统

框架提供了完整的错误页面组件,包括 403、404、500 等常见错误状态页面。

组件列表:

  • 403.vue - 权限不足页面
  • 404.vue - 页面不存在页面
  • 500.vue - 服务器错误页面

使用示例:

<template>
  <div>
    <!-- 403 权限不足 -->
    <error-403 v-if="errorCode === 403" />
    
    <!-- 404 页面不存在 -->
    <error-404 v-if="errorCode === 404" />
    
    <!-- 500 服务器错误 -->
    <error-500 v-if="errorCode === 500" />
  </div>
</template>

<script>
import Error403 from '@/components/error-page/403.vue'
import Error404 from '@/components/error-page/404.vue'
import Error500 from '@/components/error-page/500.vue'

export default {
  components: {
    Error403,
    Error404,
    Error500
  },
  data() {
    return {
      errorCode: 404
    }
  }
}
</script>

错误页面样式:

错误页面定制

所有错误页面组件都支持自定义样式和文案,可在 src/components/error-page/ 目录下进行修改。

组件注册规范

全局组件注册:

// src/main.js
import BasicContainer from '@/components/basic-container/main.vue'
import BasicBlock from '@/components/basic-block/main.vue'
import BasicVideo from '@/components/basic-video/main.vue'

// 注册全局组件
Vue.component('basic-container', BasicContainer)
Vue.component('basic-block', BasicBlock)
Vue.component('basic-video', BasicVideo)

局部组件注册:

<template>
  <div>
    <Userinfo :avatar="user.avatar" :nickname="user.nickname" />
  </div>
</template>

<script>
import Userinfo from '@/components/Userinfo/Userinfo.vue'

export default {
  components: {
    Userinfo
  }
}
</script>

组件使用提醒

  1. 全局组件无需手动引入,可直接使用
  2. 业务组件建议使用局部注册,避免全局污染
  3. 组件命名遵循 kebab-case 规范

页面生成系统

页面生成器简介

框架提供了一套强大的页面生成系统,支持一键生成完整的业务模块,包括目录结构、页面文件、API接口、路由配置等。通过可视化的配置界面,开发者可以快速创建标准化的业务页面,大幅提升开发效率。

一键生成功能

系统入口与配置

访问方式:项目本地运行(npm run dev)开发环境成功后,可进入页面生成系统,支持一键生成目录、菜单、路由、按钮权限、自定义API等功能的生成,并可以在线可视化管理。

功能特点:

  • 一键生成:支持完整的业务模块生成
  • 可视化配置:基于 Avue 表单组件的友好界面
  • 灵活定制:支持自定义API接口和按钮权限
  • 智能分类:自动区分业务页面和基础页面
  • 权限集成:自动生成按钮权限标识
  • 自定义按钮:支持一键生成自定义按钮事件和API功能
  • 模板代码:自动生成页面模板代码和事件处理方法

目录结构生成

生成流程:

  1. 开启目录模式:首先打开"是否为目录"开关

  2. 填写基础信息:

    • 目录名称:显示在菜单中的名称
    • 路由标识:英文标识,作为路由path使用
    • 重定向路径:默认为 /${route}/${route},可自定义修改
    • 选择图标:从常用目录图标库中选择
  3. 生成操作:点击生成按钮,一键生成目录结构

技术说明:

  • 生成的是网络目录和路由目录,并非本地实际目录
  • 所有生成的目录都默认为业务页面,放在 views 下
  • 框架限制目录只能一级,即目录下只能是菜单,无法嵌套目录

目录层级限制

当前框架设计为单级目录结构,目录下只能包含菜单页面,不支持多级目录嵌套。这是为了保持系统结构的简洁性。

菜单页面生成

生成流程:

  1. 关闭目录模式:默认"是否为目录"为关闭状态(页面模式)

  2. 填写页面信息:

    • 页面名称:显示在菜单中的名称
    • 父级目录:选择所属的目录
    • 是否隐藏:控制路由是否显示到菜单中(如商品详情页)
    • 路由标识:英文标识,自动同步API前缀
    • 菜单图标:选择对应的图标
  3. API配置同步:

    • 路由标识填写时,自动同步API前缀(如 member)
    • 根据API前缀生成基础接口(增删改查、修改字段、下载模板、导入、导出)
    • 支持自定义修改API配置
  4. 按钮权限生成:

    • 自动生成标准按钮(增删改查、下载模板、导入、导出)
    • 自动生成按钮权限标识(如:member_add)
  5. 文件生成:

    • 生成本地目录结构
    • 生成页面Vue文件
    • 生成API接口文件
    • 生成JS配置文件
    • 在网络菜单中添加正确路由和按钮权限
    • 在本地路由中添加对应页面路由

文件分类规则:

  • 基础页面:放在 page 目录下
  • 业务页面:放在 views 目录下
  • 分类依据:根据选择的目录判断是否为业务路由

智能文件分类

系统会根据选择的父级目录自动判断页面类型,业务相关页面放在 views 目录,基础功能页面放在 page 目录,确保项目结构清晰。

重要注意事项

关键限制说明

  1. 路由标识唯一性:新增目录时,如果路由标识一致,则视为修改操作(传path不传id)
  2. 功能按钮同步:如果页面不包含下载模板、导入、导出功能,需要在按钮配置中取消,API配置会同步取消
  3. 路由修改限制:路由本地修改功能不可用,如需修改路由,需要本地同步修改
  4. 多余文件清理:如果生成了多余的路由和页面,需要本地删除代码和路由,网络菜单中可通过"管理"按钮进行管理

模板系统架构

模板系统说明

框架采用模板引擎机制,通过变量替换生成标准化的页面文件。目前API接口模板已被启用,采用直接文件生成方式,未依赖模板系统。

Vue页面模板

模板位置:src/template/page/template.vue

模板参数说明:

参数名说明示例
{{route}}路由标识,用于组件名称和路由路径member
{{templatecode}}自定义模板代码,支持插槽定制表格列配置等
{{methodscode}}自定义方法代码,支持业务逻辑扩展自定义事件处理等

模板特点:

  • 基于 Avue-crud 组件构建
  • 支持自定义插槽(如用户信息展示)
  • 集成状态切换功能
  • 支持权限按钮控制
  • 包含完整的CRUD操作

JavaScript配置模板

模板位置:src/template/page/template.js

配置参数说明:

公共参数:

// 默认页面配置
//默认页面列表请求参数
    defaultParams: {
      //用于默认请求列表getlist()时的请求参数
    },
    editBtn: true,
    delBtn: true,
    addBtn: true,
    // 表格配置,如果是标准列表,则不需要配置
    index: true,            // 显示序号
    // 表格列配置
    column: [
      {
        label: '添加时间',
        prop: 'add_time',
        width: 180,
        display: false,
        type: 'datetime',
        searchRange: true,
        searchSpan: 6,
        defaultTime: ['00:00:00', '23:59:59'],
        search: true
      },
      {
        label: 'ID',
        prop: 'id',
        width: 80,
        disabled: true, // 不可编辑
        addDisplay: false, // 新增时不显示
        editDisplay: false, // 编辑时不显示
        hide: true // 列表隐藏(如需显示可去掉)
      },{
        label: '状态',
        prop: 'state',
        type: 'select',
        width: 80,
        value:true,
        addDisplay:false,
        dicData: [
          { label: '启用', value: 1 },
          { label: '禁用', value: 0 }
        ],
        search: true,
        searchSpan: 6
      },]

自定义参数(已注释,可在页面生成器中配置):

表格显示配置:

  • indexLabel: 序号标题(默认:'序号')
  • stripe: 斑马纹(默认:true)
  • border: 边框(默认:true)
  • size: 表格大小(默认:'default')
  • align: 对齐方式(默认:'center')
  • headerAlign: 表头对齐(默认:'center')

分页参数配置:

  • pageNumber: 页码参数名(默认:'page')
  • pageSize: 页大小参数名(默认:'limit')

数据响应配置:

  • res: 数据响应结构处理函数
  • defaultParams: 默认请求参数对象,用于请求getList时自行默认带入的

字段配置: 表格和表单字段的详细配置项较多,建议参考 Avue 官方文档-表格列配置(column) 以及 Avue 官方文档-表单配置(form) 获取最新和最全的参数说明。一些要求见表格配置规范

API方法映射(可选):

  • list: 列表接口方法名(默认:'getList')
  • add: 新增接口方法名(默认:'add')
  • update: 更新接口方法名(默认:'update')
  • del: 删除接口方法名(默认:'del')
  • import: 导入接口方法名(默认:'importData')
  • export: 导出接口方法名(默认:'exportData')
  • down: 下载模板接口方法名(默认:'downTemplate')

配置优先级说明

  1. 页面生成器配置> 模板默认值
  2. 自定义参数> 公共参数
  3. 开发者可以根据业务需求在页面生成器中覆盖默认配置

配置示例:

自定义配置示例
// 在页面生成器中配置的自定义参数
{
  defaultParams: {//将在请求列表时默认带入参数
    status: 1,
    type: 'active'
  },
  index: false,              // 不显示序号
  stripe: false,             // 不显示斑马纹
  size: 'small',             // 小型表格
  align: 'left',             // 左对齐
  pageNumber: 'page',        // 自定义页码参数名
  pageSize: 'limit',         // 自定义页大小参数名
  res: (res) => ({           // 自定义响应数据处理
    data: res.data,
    total: res.total
  })
}

API接口模板

API模板弃用说明

API接口模板已被弃用,目前采用 直接生成API文件内容,不再依赖模板系统。

API文件生成规则:

生成逻辑:

  1. 文件头部:自动添加注释和导入语句
  2. 接口遍历:遍历配置的API数组
  3. 参数处理:根据请求方法自动选择参数名
    • GET请求:使用 params 参数
    • POST请求:使用 data 参数
  4. 方法生成:生成标准化的请求函数

生成的标准接口:

  • getList: 获取列表数据
  • add: 新增数据
  • update: 更新数据
  • del: 删除数据
  • modify_field: 修改字段
  • importData: 导入数据
  • exportData: 导出数据
  • downTemplate: 下载模板
API文件生成示例
// 自动生成的API文件结构
import request from '@/axios';

// 获取列表
export const getList = (params) => {
  return request({
    url: '/member/get_list',
    method: 'get',
    params
  })
}

// 新增数据
export const add = (data) => {
  return request({
    url: '/member/add',
    method: 'post',
    data
  })
}

自定义按钮生成功能

自定义按钮功能

页面生成器支持一键生成自定义按钮事件、API功能和权限配置,大幅提升开发效率。

功能特点:

  • 智能按钮生成:根据按钮配置自动生成自定义操作按钮
  • 事件处理生成:自动生成对应的事件处理方法
  • 权限集成:自动生成按钮权限配置
  • 模板代码生成:自动生成页面模板代码
  • 方法命名规范:遵循驼峰命名规范

命名规则:

事件方法命名规范:

  • 格式:handle_${操作类型}
  • 示例:handle_export、handle_import、handle_download

权限命名规范:

  • 格式:${模块名}_${操作类型}
  • 示例:member_export、member_import、member_download

生成示例:自定义按钮

注意事项:

手动自定义按钮注意事项

  1. 权限配置:自定义按钮需要配置对应的权限标识
  2. 方法命名:自动生成的方法名遵循驼峰命名规范
  3. 模板集成:生成的代码会自动集成到页面模板中
  4. 权限验证:按钮显示会根据用户权限自动控制
  5. 事件处理:生成的方法需要根据业务需求进行完善

开发规范

开发规范说明

为了确保项目代码的一致性和可维护性,框架制定了一套完整的开发规范。遵循这些规范可以提升开发效率,减少代码错误,便于团队协作。

代码规范检查清单

接口命名与URL规范

标准接口命名
  • 列表接口: getList - 获取数据列表
  • 新增接口: add - 新增数据
  • 编辑接口: update - 更新数据
  • 删除接口: del - 删除数据
  • 导入接口: importData - 导入数据
  • 导出接口: exportData - 导出数据
  • 下载模板: downTemplate - 下载模板文件
GET    /admin/{module}/get_list     # 获取列表
POST   /admin/{module}/add          # 新增数据
POST   /admin/{module}/edit         # 编辑数据
POST   /admin/{module}/del          # 删除数据
POST   /admin/{module}/import       # 导入数据
POST   /admin/{module}/export       # 导出数据
GET    /admin/{module}/template     # 下载模板
GET    /admin/{module}/get_select   # 下拉选择接口
HTTP方法使用规范
  • GET: 获取数据,参数通过query传递
  • POST: 提交数据,参数通过body传递
  • POST: 更新数据,参数通过body传递
  • POST: 删除数据,参数通过body传递
响应数据结构
// 成功响应格式
{
    "code": 200,
    "datas": {
    // 具体数据
  }
}

分页数据格式

//分页数据格式
{
    "code": 200,
    "datas": {
    'num': 100,    // 总条数
    'data': []       // 数据列表
  }
}

下拉选择接口

//下拉选择接口格式
{
    "code": 200,
    'datas': []       // 数据列表
}

加密的使用

在 src/config/settings.js 中配置:

api: {
  enableEncryption: true,  // 开启加密
  encryptionKey: 'your-key' // 加密密匙推荐为数据库密码
}

服务端加密配置

  • 在数据库 database.php 中关闭 debug 模式
  • encryptionKey 必须与后端数据库密码一致
  • 确保前后端加密算法一致

API命名注意事项

  1. 接口名称必须使用驼峰命名法
  2. URL路径使用小写字母和连字符
  3. 保持接口命名的一致性和语义化
  4. 避免使用缩写,确保接口名称清晰易懂

按钮命名规范

标准按钮权限命名:

  • 新增按钮:${route}_add
  • 编辑按钮:${route}_edit
  • 删除按钮:${route}_del
  • 详情按钮:${route}_detail
  • 导入按钮:${route}_import
  • 导出按钮:${route}_export
  • 下载模板:${route}_down

自定义按钮命名:

  • 格式:${模块名}_${操作类型}
  • 示例:member_export、article_publish、user_reset

按钮权限命名规范

按钮权限标识采用 模块名_操作类型 的命名方式,确保权限管理的规范性和可维护性。

字段命名规范

数据库字段命名:

  • 使用下划线命名法(snake_case)
  • 主键统一使用 id
  • 创建时间使用 add_time
  • 更新时间使用 update_time
  • 状态控制字段使用 state
  • 删除标记使用 is_del
  • 排序标识使用 sort
  • 外连表id使用 table_id

前端字段命名:

  • 使用驼峰命名法(camelCase)
  • 与后端字段对应,如:addTime、updateTime
  • 布尔值字段使用 is 前缀,如:isVisible、isEnabled

字段命名最佳实践

  1. 保持前后端字段命名的一致性
  2. 使用语义化的字段名称
  3. 避免使用缩写,确保字段名称清晰易懂
  4. 遵循框架的命名约定

文件组织规范

目录结构规范:

src/
├── page/           # 基础页面
│   ├── {module}/   # 模块目录
│   │   ├── {module}.vue      # 页面文件
│   │   ├── {module}.js       # 配置文件
│   │   └── api_{module}.js   # API接口文件
├── views/          # 业务页面
│   ├── {module}/   # 模块目录
│   │   ├── {module}.vue      # 页面文件
│   │   ├── {module}.js       # 配置文件
│   │   └── api_{module}.js   # API接口文件
└── components/     # 公共组件
    ├── basic-*     # 基础组件
    └── {module}/   # 业务组件

文件命名规范:

  • 页面文件:{module}.vue
  • 配置文件:{module}.js
  • API文件:api_{module}.js
  • 组件文件:{ComponentName}.vue

文件组织最佳实践

  1. 按功能模块组织文件
  2. 保持目录结构的清晰性
  3. 遵循框架的目录约定
  4. 避免文件命名冲突

样式编写规范

CSS类命名规范:

  • 使用 BEM 命名法(Block-Element-Modifier)
  • 使用 kebab-case 命名
  • 保持类名的语义化

样式组织规范:

// 组件样式
.component-name {
  // 基础样式
  
  &__element {
    // 元素样式
  }
  
  &--modifier {
    // 修饰符样式
  }
}

// 全局样式
.global-class {
  // 全局样式定义
}

样式编写原则:

  1. 模块化:样式按模块组织
  2. 可维护性:样式结构清晰
  3. 可扩展性:样式易于扩展
  4. 性能优化:避免样式冲突

样式编写最佳实践

  1. 使用 scoped 样式避免全局污染
  2. 合理使用 CSS 变量
  3. 遵循移动优先的响应式设计
  4. 保持样式的可读性和可维护性

字段合并展示规范

重要提醒

如果页面展示需要合并多个字段到一个表格单元格,一定要使用HTML转义,避免XSS攻击风险。

正确的合并字段方式:

// 表格列配置示例
{
  label: '时间范围',
  prop: 'time_range',
  width: 200,
  html: true,  // 启用HTML渲染
  formatter: (row, column, cellValue, index) => {
    // 使用模板字符串安全地合并字段
    return `<div>开始:${row.start_time}<br/>结束:${row.end_time}</div>`
  }
}

错误的合并方式(存在安全风险):

// 错误示例 - 直接拼接字符串
formatter: (row, column, cellValue, index) => {
  return '开始:' + row.start_time + '<br/>结束:' + row.end_time
}

// 错误示例 - 未启用HTML渲染
formatter: (row, column, cellValue, index) => {
  return `<div>开始:${row.start_time}<br/>结束:${row.end_time}</div>`
}

安全合并字段的最佳实践:

  1. 启用HTML渲染:
{
  html: true,  // 必须设置为true
  formatter: (row, column, cellValue, index) => {
    // 格式化逻辑
  }
}
  1. 使用模板字符串:
formatter: (row, column, cellValue, index) => {
  return `<div class="time-range">
    <span class="start">开始: ${row.start_time}</span>
    <br/>
    <span class="end">结束: ${row.end_time}</span>
  </div>`
}
  1. 复杂字段合并示例:
formatter: (row, column, cellValue, index) => {
  return `<div class="user-info">
    <div class="name">姓名: ${row.name}</div>
    <div class="phone">电话: ${row.phone}</div>
    <div class="email">邮箱: ${row.email}</div>
  </div>`
}

字段合并安全提示

  1. 必须设置 html: true:否则HTML标签会被转义显示
  2. 使用模板字符串:避免字符串拼接的安全风险
  3. 注意数据来源:确保字段数据来自可信源
  4. 避免用户输入:不要在formatter中直接使用用户输入的数据

安全警告

如果字段数据来自用户输入,必须进行HTML转义处理:

import { escape } from 'lodash-es'

formatter: (row, column, cellValue, index) => {
  const safeStartTime = escape(row.start_time)
  const safeEndTime = escape(row.end_time)
  return `<div>开始:${safeStartTime}<br/>结束:${safeEndTime}</div>`
}
最近更新: 2025/8/17 19:02
Contributors: litaipingwy, 印留时光