c#网站开发工具,网站编程赚钱,假的建设银行网站,哈尔滨网站建设网站制作【JSON2WEB】01 WEB管理信息系统架构设计
【JSON2WEB】02 JSON2WEB初步UI设计
【JSON2WEB】03 go的模板包html/template的使用
【JSON2WEB】04 amis低代码前端框架介绍
【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成
【JSON2WEB】06 JSON2WEB前端框架搭建
【J…【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_modfrom 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_ynfrom 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 distinctm.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为用户Idlayer为导航菜单的层级我一般只用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] datasetreturn 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 validateresToken : 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] 401rw[msg] 用户ID或密码无效}// http://127.0.0.1:5217/TOKEN/generate-token?userid9998passwd8999// curl http://127.0.0.1:5217/TOKEN/generate-token?userid9998passwd8999case 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] 401rw[msg] 无效token}dataMap : make(map[string]interface{})dataMap[rows] rowsMap[rows]dataMap[token] tokenMap[token]rw[data] dataMap// 输出到 http.ResponseWriterhttpResWriter(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$userIdpasswd$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);// 字符串转jsonlet 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 动态导航菜单加载成功
动态导航菜单加载成功测试各页面操作正常。 本文完。