【JSON2WEB】 12基于Amis-admin的动态导航菜单树

news2025/1/19 7:59:48

【JSON2WEB】01 WEB管理信息系统架构设计

【JSON2WEB】02 JSON2WEB初步UI设计

【JSON2WEB】03 go的模板包html/template的使用

【JSON2WEB】04 amis低代码前端框架介绍

【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成

【JSON2WEB】06 JSON2WEB前端框架搭建

【JSON2WEB】07 Amis可视化设计器CRUD增删改查

【JSON2WEB】08 Amis的事件和校验

【JSON2WEB】09 Amis-editor的代码移植到json2web

【JSON2WEB】10 基于 Amis 做个登录页面login.html

【JSON2WEB】11 基于 Amis 角色功能权限设置页面


管理信息系统一般注册用户较多,功能页面也很多,不同用户有不同的功能页面的操作权限,根据用户角色功能权限,生成动态的页面导航功能树是我采用的常规操作。

1 动态菜单的设计

关于数据库的表设计参阅 【REST2SQL】13 用户角色功能权限设计。

1.1 创建几个相关视图

  • 角色-页面权限视图
create or replace view role_menu_v as
select m.p_id as m_id,m.s_name ,s.pf_role,r.p_id as r_id,
  decode(length(s.pf_role),4,1,0) as b_yn,m.f_mod
 from s_menu m
cross join s_role r --先做一个角色与功能的笛卡尔交叉,再连接角色功能表
left join s_role_menu s on s.pf_menu = m.p_id and s.pf_role = r.p_id
order by r.p_id,m.p_id
;

在这里插入图片描述

  • 用户-角色视图
create or replace view user_role_v as
select r.p_id as r_id,r.s_name ,s.pf_user,u.p_id as u_id,
  decode(length(s.pf_role),4,1,0) as b_yn
 from s_role r
cross join s_user u --先做一个用户与角色的笛卡尔交叉,再连接用户角色表
left join s_user_role s on s.pf_user = u.p_id and s.pf_role = r.p_id
order by u.p_id,r.p_id
;

在这里插入图片描述

  • 用户-角色-页面视图
create or replace view user_role_menu_v as
select distinct
       m.p_id || m.s_name || nvl(m.s_note,'') as s_name,
        m.s_WINp,
         m.s_PARM,
         m.p_id as pf_menu,
         m.s_note,
         --u.pf_role,
         u.pf_user,
         m.f_mod
from s_user_role u -- 用户 - 角色 = 功能视图
left join s_role_menu r on r.pf_role = u.pf_role
left join s_menu m on m.p_id = r.pf_menu
order by u.pf_user, m.p_id
;

在这里插入图片描述

  • 用户-页面视图
create or replace view user_page_v as
select s_name as label,
       pf_menu as url,
       s_winp as schemaApi,
       pf_user as userid,
       decode(substr(pf_menu,2,3),'000',1,2) as layer
from USER_ROLE_MENU_V -- 用户功能页面
where f_mod = 'BS'
;

在这里插入图片描述
这个视图就是最后动态菜单树要呈现的内容,label,url,schemaapi是amin-admin矿建的要求,userid为用户Id,layer为导航菜单的层级,我一般只用2级。

2 后端实现

前端登录时发送过来用户ID,根据用户id获得页面权限列表和token。后端我还是用REST2SQL来实现。

2.1 创建获取用户页面的函数

代码如下:

/ 获取用户页面
func getUserPages(userId string) map[string]interface{} {
	selectSQL := "select label,url,schemaApi,layer from user_page_v where userid = '" + userId + "'"

	//执行 sql并返回 json 结果
	logger.Alog(true, fmt.Sprint("getUserPage:", selectSQL))

	result := Icrud.SelectData(selectSQL)

	// json串反序列化
	var dataset []map[string]interface{}
	err := json.Unmarshal([]byte(result), &dataset)
	if err != nil {
		fmt.Println("Error:", err)
		return nil
	}

	rows := make(map[string]interface{})
	rows["rows"] = dataset
	return rows
}

输入参数用户ID,返回一个map。

2.2 doToken()函数的修改

用户验证成功后,获取用户页面功能列表。

// 根据请求参数执行不同的TOKEN操作 ///
func doTOKEN(w http.ResponseWriter, req map[string]interface{}) {
	// 返回数据
	rw := returnMap()

	rowsMap := make(map[string]interface{})

	tokenMap := make(map[string]interface{})
	// token操作, generate or validate
	resToken := strings.ToLower(req["ResName"].(string))
	switch resToken {
	case "generate-token":
		// w.Write([]byte("generate-token"))
		var uid_pwd map[string]string = make(map[string]string)
		uid_pwd["Userid"] = req["Userid"].(string)
		uid_pwd["Passwd"] = req["Passwd"].(string)
		// 用户名及密码验证
		ret1 := uidPwdIsValid(uid_pwd)

		if ret1 == 1 {
			//fmt.Println(ret1)
			tokenMap = token.GenerateTokenHandler(w, uid_pwd)
			rw["msg"] = "恭喜您登录成功!"
			// 获取功能页面列表
			rowsMap = getUserPages(uid_pwd["Userid"])
			//fmt.Println(rowsMap)

		} else {
			tokenMap["token"] = "无效用户Id:" + uid_pwd["Userid"] + "或密码" + uid_pwd["Passwd"]
			rw["status"] = 401
			rw["msg"] = "用户ID或密码无效!"
		}

		// http://127.0.0.1:5217/TOKEN/generate-token?userid=9998&passwd=8999

		// curl "http://127.0.0.1:5217/TOKEN/generate-token?userid=9998&passwd=8999"

	case "validate-token":
		//w.Write([]byte("validate-token"))
		var tokenString string = req["Authorization"].(string)
		fmt.Println(tokenString)
		tokenMap = token.ValidateTokenHandler(w, tokenString)

		// curl http://localhost:5217/token/validate-token -H "Authorization:token"
	}

	// 返回数据
	if tokenMap == nil {
		rw["status"] = 401
		rw["msg"] = "无效token"
	}
	dataMap := make(map[string]interface{})
	dataMap["rows"] = rowsMap["rows"]
	dataMap["token"] = tokenMap["token"]
	rw["data"] = dataMap

	// 输出到 http.ResponseWriter
	httpResWriter(w, rw)
}

就是返回token和用户页面列表,Json内容如下:


{
  "data": {
    "rows": [
      {
        "LABEL": "Z000系统管理",
        "LAYER": 1,
        "SCHEMAAPI": null,
        "URL": "Z000"
      },
      {
        "LABEL": "Z010页面管理",
        "LAYER": 2,
        "SCHEMAAPI": "page.json",
        "URL": "Z010"
      },
      {
        "LABEL": "Z020角色管理",
        "LAYER": 2,
        "SCHEMAAPI": "role.json",
        "URL": "Z020"
      },
      {
        "LABEL": "Z030角色功能权限设置",
        "LAYER": 2,
        "SCHEMAAPI": "role_menu.json",
        "URL": "Z030"
      },
      {
        "LABEL": "Z040用户管理",
        "LAYER": 2,
        "SCHEMAAPI": "user.json",
        "URL": "Z040"
      },
      {
        "LABEL": "Z050用户角色设置",
        "LAYER": 2,
        "SCHEMAAPI": "user_role.json",
        "URL": "Z050"
      }
    ],
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOiI1NDQ0IiwicGFzc3dkIjoiNDQ0NSIsImV4cCI6MTcxMjE1MjE4NiwiaXNzIjoiNTIxN-iCoeWKoemZoiJ9.H13dcOP6I4LV-KbCKsr8kYmtO3_jwf3QJ3uvk7Goy2k"
  },
  "msg": "恭喜您登录成功!",
  "status": 0
}

用户页面是要按层级排序的。

3 前端实现

登录成功后,保存用户页面列表,主页获取导航site.json时加入,用户功能页面。

3.1 site.json页面

{
  "status": 0,
  "msg": "",
  "data": {
    "pages": [
      {
        "label": "Home",
        "url": "/",
        "redirect": "welcome"
      },
      {
        "label": "导航树",
        "children": [
          {
            "label": "Welcome to Json2Web",
            "url": "welcome",
            "schemaApi": "get:/pages/hello.json"
          }          
        ]
      },
      {
        "label": "示例",
        "children": [
          {
            "label": "REST2SQL",
            "link": "https://blog.csdn.net/html5builder/article/details/135544119"
          },
          {
            "label": "JSON2WEB",
            "link": "https://blog.csdn.net/html5builder/article/details/135698948"
          },
          {
            "label": "AMIS文档",
            "link": "https://aisuda.bce.baidu.com/amis/zh-CN/docs/index"
          }
        ]
      }
    ]
  }
}

动态页面菜单就加在【导航树】的节点下面。

3.2 login.html登录页面

只需要成功后,保存下来用户功能页面即可。api代码如下:

api: {
            url: 'http://127.0.0.1:5217/token/generate-token?userid=$userId&passwd=$passWd',
            method: 'get',
            adaptor: function (payload) {
              console.log(payload);
              if (payload.status === 0) {
                localStorage.setItem('token', payload.data.token);
                let rows = JSON.stringify(payload.data.rows)
                // console.log('rows',rows);
                localStorage.setItem('rows', rows);
                // localStorage.clear(); location.href = '/login.html';
                return payload;
              }
            }
          },

关键代码就两行:

	let rows = JSON.stringify(payload.data.rows)
	// console.log('rows',rows);
	localStorage.setItem('rows', rows);

先把json对象转为json字符串,在保存到loacaStorage中。

3.2 index.html主页

原来页面导航的api如下:

api:'/pages/site.json'

增加接收适配器代码如下:

api: {
          url: '/pages/site.json',
          adaptor: function (payload) {
            console.log('Payload', payload);
            // 页面权限字符串
            let rows = localStorage.getItem("rows");
            // 字符串转json
            let pageJson = JSON.parse(rows);
            console.log('pageJson:', pageJson);
            // 要插入菜单的节点
            let pages = payload.data.pages[1];
            console.log('pages:', pages);
            // 创建动态菜单

            pageJson.map(function (page) {
              let layers = page.LAYER;
              let labels = page.LABEL;
              let schemaApis = 'get:/pages/' + page.SCHEMAAPI;
              let urls = page.URL;
              let l1 = pages.children.length;
              
              if (layers == 1) {
                // 插入一级菜单               
                pages.children[l1] = {label:labels,"children":[]};
              } else {    
                // 插入二级菜单
                let l2 =  pages.children[l1 - 1].children.length;       
                pages.children[l1 - 1].children[l2] = {label:labels,url:urls,schemaApi:schemaApis};  
              };
            });
            // 返回
            return payload;
          }
        }

注:先取出保存的用户页面列表Json字符串并转为json对象方便操作,再定位要插入导航节点,三采用map循环创建动态菜单(根据层级构建,一级只有label,和children[];二级还有url和schemaapi)。

4 实操演练

4.1 登录

在这里插入图片描述
输入用户名和密码点【提交】即可。

4.2 欢迎页面

登录成功切换到主页的欢迎页面:

在这里插入图片描述

4.3 动态导航菜单加载成功

动态导航菜单加载成功,测试各页面操作正常。
在这里插入图片描述


本文完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1572080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Visual Studio安装下载进度为零已解决

因为在安装pytorch3d0.3.0时遇到问题,提示没有cl.exe,VS的C编译组件,可以添加组件也可以重装VS。查了下2019版比2022问题少,选择了安装2019版,下面是下载安装时遇到的问题记录,关于下载进度为零网上有三类解…

Redis-底层数据结构

Redis-底层数据结构 redisObject对象机制对象共享引用计数以及对象的消毁 动态字符串SDS链表链表的优缺点: 压缩链表ziplist的缺点 字典-Dictrehash渐进式rehash 整数集-intSet内存分布图整数集合的升级 跳表 - ZSkipList快表-quicklistlistpack redisObject对象机制 typedef s…

HFSS仿真环形耦合器学习笔记

HFSS仿真环形耦合器学习笔记 文章目录 HFSS仿真环形耦合器学习笔记1、 理论基础2、 设计分析3、 仿真验证1、 求解器设置2、 建模3、 激励方式设置4、 边界条件设置5、 扫频设置6、 设计检查,仿真分析7、 数据后处理 1、 理论基础 环形定向耦合器的结构示意图如图所…

Android 关于apk反编译d2j-dex2jar classes.dex失败的几种方法

目录 确认路径正确直接定位到指定目录确定目录正确,按如下路径修改下面是未找到相关文件正确操作 确认路径正确 ,即d2j-dex2jar和classes.dex是否都在一个文件夹里(大部分的情况都是路径不正确) 直接定位到指定目录 路径正确的…

Linux 安装系统可视化监控工具 Netdata

目录 About 监控工具 NetdataLinux 系统安装 Netdata关于 openEuler1、查看内核信息2、查看主机信息3、查看 dnf 包管理器的版本 Netdata 安装1、更新系统环境相关 rpm 包2、查看 netdata 包信息3、安装 netdata 包4、编辑 netdata.conf 配置5、启动 netdata 服务6、查看 netda…

深入浅出 -- 系统架构之微服务架构常见的六种设计模式

面向服务的架构(SOA) 面向服务的架构(SOA)是一种设计方法,也是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的…

JAVA毕业设计132—基于Java+Springboot+Vue的自习室座位预约小程序管理系统(源代码+数据库)

毕设所有选题: https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的自习室座位预约小程序管理系统(源代码数据库)132 一、系统介绍 本项目前后端分离带小程序,分为管理员、用户两种角色 1、用户: 注…

数学与人工智能:共舞于数字时代的奥秘

数学,这一源远流长的学科,长久以来一直为人类社会的发展与进步提供了坚实的基础。与此同时,随着科技的迅猛发展,人工智能这一新兴领域正逐渐改变着我们的生活方式。这两者之间,似乎存在着一种难以言喻的紧密联系。本文…

苍穹外卖——项目搭建

一、项目介绍以及环境搭建 1.苍穹外卖项目介绍 1.1项目介绍 本项目(苍穹外卖)是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包括 系统管理后台 和 小程序端应用 两部分。其中系统管理后台主要提供给餐饮企业内部员…

android11 SystemUI入門之KeyguardPatternView解析

view层级树为&#xff1a; 被包含在 keyguard_host_view.xml中 。 <?xml version"1.0" encoding"utf-8"?> <!-- This is the host view that generally contains two sub views: the widget viewand the security view. --> <com.andro…

SQL注入---文件上传+Webshell

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.Web工作原理 Web工作原理详解 HTTP/HTTPS协议会作为浏览器中输入信息的载体&#xff0c;向目标服务器发送请求&#xff0c;目标服务器收到请求后再返回对饮的信息&#xff0c;其中浏览器中…

【论文精读】Detecting Out-of-Distribution Examples with Gram Matrices 使用Gram矩阵检测分布外实例

文章目录 一、文章概览&#xff08;一&#xff09;Gram矩阵1、Gram&#xff08;格朗姆&#xff09;矩阵的定义2、Gram矩阵计算特征表示3、风格迁移中的Gram矩阵 &#xff08;二&#xff09;ood检测&#xff08;三&#xff09;核心思路&#xff1a;扩展 Gram 矩阵以进行分布外检…

Google视觉机器人超级汇总:从RT、RT-2到AutoRT、SARA-RT、RT-Trajectory

前言 随着对视觉语言机器人研究的深入&#xff0c;发现Google的工作很值得深挖&#xff0c;比如RT-2 ​想到很多工作都是站在Google的肩上做产品和应用&#xff0c;​Google真是科技进步的核心推动力&#xff0c;做了大量大模型的基础设施&#xff0c;服 故有了本文&#xf…

【优选算法专栏】专题十六:BFS解决最短路问题---前言

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

Redis Desktop Manager可视化工具

可视化工具 Redis https://www.alipan.com/s/uHSbg14XmsL 提取码: 38cl 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视频原画倍速播放。 官网下载&#xff08;不推荐&#xff09;&#xff1a;http…

mysql知识点梳理

mysql知识点梳理 一、InnoDB引擎中的索引策略&#xff0c;了解过吗&#xff1f;二、一条 sql 执行过长的时间&#xff0c;你如何优化&#xff0c;从哪些方面入手&#xff1f;三、索引有哪几种类型&#xff1f;四、SQL 约束有哪几种呢&#xff1f;五、drop、delete、truncate的区…

ES学习日记(八)-------ik安装和简易使用

一、下载和安装 https://github.com/infinilabs/analysis-ik.git 网络不好可以用这个地址,注意:ik版本要和es版本保持一致 现成地址 注意es用户操作或给es用户权限 plugins新建ik文件夹,并把压缩包解压到ik unzip elasticsearch-analysis-ik-7.4.2.zip /bin目录启动es: 二…

游戏攻略|基于Springboot和vue的游戏分享平台系统设计与实现(源码+数据库+文档)

游戏攻略分享平台目录 基于Springboot的在线考试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台&#xff1a; 2、后台 5.2.1管理员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; …

练手项目层中阶2—《详解动态版本——通讯录管理系统》

文章目录 &#x1f3f3;‍&#x1f308;前言&#x1f50a;项目需求&#x1f4dd;项目知识点包含&#x1f9e9;项目框架&#x1f511;框架拆解分析&#x1f4da;Struct_Book1.h头文件分析&#x1f4da;Struct_Book1.c源文件分析&#x1f4da;test_book.c源文件分析 &#x1f3a5…

MySql并发事务问题

事务 事务概念&#xff1a; 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务的特性&#xff1a;ACID&#xff1a; 小…