对于职位管理,我们可以理解它为角色权限的管理,就像前面所说的一样,有了职位管理,后台管理系统绑定好对应的权限以后,新进员工、离职或岗位调整,管理员操作起来就非常的便捷了,只需要重新绑定对应职位就可以做好权限的切换工作。

  为了方便职位管理,我们可以将页面设计成下面这个样子

  左边显示部分列表,点击其中一个项后,右边显示对应部门的职位,然后再对职位进行增、改、删等操作

  左边我们可以直接使用上一章的部门列表接口,然后将jqGrid前端组件修改一下,只显示名称一列就可以了

  然后在前端代码中的jqGrid组件中,增加onSelectRow方法,点击列表项时执行右边列表查询和刷新操作就可以了。

  右边需要增加职位列表查询接口,查询时需要提交部门id作为查询条件,具体接口代码如下:

 @get('/system/positions/')
def callback():
"""
获取列表数据
"""
# 部门id
department_id = convert_helper.to_int0(web_helper.get_query('department_id', '部门id'))
# 页面索引
page_number = convert_helper.to_int1(web_helper.get_query('page', '', is_check_null=False))
# 页面页码与显示记录数量
page_size = convert_helper.to_int0(web_helper.get_query('rows', '', is_check_null=False))
sidx = web_helper.get_query('sidx', '', is_check_null=False)
sord = web_helper.get_query('sord', '', is_check_null=False)
# 初始化排序字段
order_by = 'id asc'
if sidx:
order_by = sidx + ' ' + sord _positions_logic = positions_logic.PositionsLogic()
# 读取记录
wheres = ''
if department_id:
wheres = 'department_id=' + str(department_id)
result = _positions_logic.get_list('*', wheres, page_number, page_size, order_by)
if result:
# 直接输出json
return json.dumps(result)
else:
return web_helper.return_msg(-1, "查询失败")

  代码看起来是否感觉很熟悉,和前端列表查询的代码差不多,只是接收参数、查询条件和调用的类不一样而已。所以我们只需要熟悉工具函数、底层ORM方法和调用方法,写起代码来就非常便捷,代码的可读性也大大增强了。

  接着我们来处理新增职位操作,新增职位时,需要管理填写的内容只有职位名称,因为所属部门与部门编码在页面中可以直接带过来,另一个操作就是设置访问权限了,这也是我们整个权限管理中最重要的一个环节

  由上图可以看到,设置访问权限它是一个树列表,它使用的是ztree控件,按它要求的格式,将列表值传给ztree控件就可以自动生成这样的树列表了,然后前端代码通过ztree控件的onCheck方法,获取所有勾选项对应的菜单项id,组合成权限字串提交到接口,更新到数据表中,该职位就拥有了我们所勾选的所有权限了。

  对于访问权限树列表的展示,首先,它需要读取菜单列表,输出ztree控件要求的格式;其次,我们在编辑职位权限时,需要对已拥有权限的项自动打上勾,这个我们也可以直接在接口中输出对应的参数来进行设置。

  所以我们可以在上一章的menu_info.py文件中,增加下面接口来处理,通过提交过来的职位id,来获取该职位拥有的权限,然后通过逐项判断菜单项与权限的关系,来判断是否打勾。

 @get('/api/system/menu_info/positions/<id:int>/')
def callback(id):
"""
根据用户职位权限获取列表数据(树列表),为已有权限的数据赋值
"""
_menu_info_logic = menu_info_logic.MenuInfoLogic()
# 读取记录(ztree控件需要输出记录id、父id、树节点名称、节点是否扩开这几项参数)
result = _menu_info_logic.get_list('id, parent_id, name, not is_leaf as open, false as checked')
if result and result.get('rows'):
# 获取指定的职位记录
_positions_logic = positions_logic.PositionsLogic()
positions_logic_model = _positions_logic.get_model_for_cache(id)
if positions_logic_model:
# 读取该职位权限字串
page_power = positions_logic_model.get('page_power', '')
# 判断当前菜单项id是否存在于该职位的权限字串中
for model in result.get('rows'):
# 如果存在,则表示当前职位拥有该菜单项的权限,即在菜单权限列表中需要打勾
if ',' + str(model.get('id', 0)) + ',' in page_power:
model['checked'] = True return web_helper.return_msg(0, "成功", {'tree_list': result.get('rows')})
else:
return web_helper.return_msg(-1, "查询失败")

  我们再来看看点击保存后,执行新增职位记录接口代码是怎么实现的

 @post('/system/positions/')
def callback():
"""
新增记录
"""
name = web_helper.get_form('name', '角色名称')
department_id = convert_helper.to_int0(web_helper.get_form('department_id', '部门id'))
page_power = web_helper.get_form('page_power', '权限列表', is_check_null=False) _department_logic = department_logic.DepartmentLogic()
# 读取对应的部门记录
department_result = _department_logic.get_model_for_cache(department_id)
if not department_result:
return web_helper.return_msg(-1, "部门不存在") _positions_logic = positions_logic.PositionsLogic()
# 组合更新字段
fields = {
'name': string(name),
'department_id': department_id,
'department_code': string(department_result.get('code', '')),
'department_name': string(department_result.get('name', '')),
'page_power': string(page_power),
}
# 读取记录
result = _positions_logic.add_model(fields)
if result:
# 直接输出json
return web_helper.return_msg(0, '提交成功')
else:
return web_helper.return_msg(-1, "提交失败")

  这段代码跟之前的新增也差不多,先是接收提交的参数,然后组合更新字典,再调用提交到数据表。

  修改职位权限功能跟上面的类似,不过接口中需要增加一个获取职位记录实体的接口

 @get('/system/positions/<id:int>/')
def callback(id):
"""
获取指定记录
"""
_positions_logic = positions_logic.PositionsLogic()
# 读取记录
result = _positions_logic.get_model_for_cache(id)
if result:
# 直接输出json
return web_helper.return_msg(0, '成功', result)
else:
return web_helper.return_msg(-1, "查询失败") @put('/system/positions/<id:int>/')
def callback(id):
"""
修改记录
"""
name = web_helper.get_form('name', '角色名称')
department_id = convert_helper.to_int0(web_helper.get_form('department_id', '部门id'))
page_power = web_helper.get_form('page_power', '权限列表', is_check_null=False)
if page_power == ',':
page_power = '' _positions_logic = positions_logic.PositionsLogic()
positions_result = _positions_logic.get_model_for_cache(id)
if department_id != positions_result.get('department_id'):
return web_helper.return_msg(-1, '该角色所属部门错误,请与管理员联系') # 组合更新字段
fields = {
'name': string(name),
'page_power': string(page_power),
} # 读取记录
result = _positions_logic.edit_model(id, fields)
if result:
# 直接输出json
return web_helper.return_msg(0, '提交成功', result)
else:
return web_helper.return_msg(-1, "提交失败")

  最后是删除接口,我们在执行删除操作时,一定要判断它是否已绑定了管理员账号,不然直接删除后,管理员登录后台系统以后将没有任何权限,无法做任何操作。

 @delete('/system/positions/<id:int>/')
def callback(id):
"""
删除指定记录
"""
# 判断要删除的记录是否被引用,是的话不能删除
_manager_logic = manager_logic.ManagerLogic()
if _manager_logic.exists('positions_id=' + str(id)):
return web_helper.return_msg(-1, "当前职位已绑定相关管理员,不能直接删除") # 删除记录
_positions_logic = positions_logic.PositionsLogic()
result = _positions_logic.delete_model(id)
if result:
# 直接输出json
return web_helper.return_msg(0, '删除成功')
else:
return web_helper.return_msg(-1, "删除失败")

  最后,大家参照上一章节,在菜单中添加对应的职位管理菜单和控件就可以开始使用了

  

  本文对应的源码下载 

版权声明:本文原创发表于 博客园,作者为 AllEmpty 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

python开发QQ群:669058475(本群已满)、733466321(可以加2群)    作者博客:http://www.cnblogs.com/EmptyFS/

我的第一个python web开发框架(37)——职位管理功能的更多相关文章

  1. 我的第一个python web开发框架(41)——总结

    我的第一个python web开发框架系列博文从17年6.7月份开始写(存了近十章稿留到9月份才开始发布),到今天结束,一年多时间,想想真不容易啊. 整个过程断断续续,中间有段时间由于工作繁忙停了好长 ...

  2. 我的第一个python web开发框架(14)——后台管理系统登录功能

    接下来正式进入网站的功能开发.要完成后台管理系统登录功能,通过查看登录页面,我们可以了解到,我们需要编写验证码图片获取接口和登录处理接口,然后在登录页面的HTML上编写AJAX. 在进行接口开发之前, ...

  3. 我的第一个python web开发框架(1)——前言

    由于之前经验不是很丰富,写的C#系统太过复杂,所以一直想重写,但学的越多越觉得自己懂的越少,越觉的底气不足.所以一直不敢动手,在内心深处对自己讲,要静下心来认真学习,继续沉淀沉淀.这两年多以来找各种机 ...

  4. 我的第一个python web开发框架(3)——怎么开始?

    小白与小美公司经过几次接触商谈,好不容易将外包签订了下来,准备开始大干一场.不过小白由于没有太多的项目经验,学过python懂得python的基本语法,在公司跟着大家做过简单功能,另外还会一些HTML ...

  5. 我的第一个python web开发框架(21)——小结

    这个小网站终于成功上线,小白除了收获一笔不多的费用外,还得到女神小美的赞赏,心中满满的成就感.这一天下班后,他请老菜一起下馆子,兑现请吃饭的承诺,顺便让老菜点评一下. 小白:老大,在你的指导下终于完成 ...

  6. 我的第一个python web开发框架(39)——后台接口权限访问控制处理

    前面的菜单.部门.职位与管理员管理功能完成后,接下来要处理的是将它们关联起来,根据职位管理中选定的权限控制菜单显示以及页面数据的访问和操作. 那么要怎么改造呢?我们可以通过用户的操作步骤来一步步进行处 ...

  7. 我的第一个python web开发框架(22)——一个安全小事故

    在周末的一个早上,小白还在做着美梦,就收到了小美的连环追魂call,电话一直响个不停. 小白打着哈欠拿起电话:早上好美女. 小美:出事了出事了,我们公司网站一早访问是一片空白,什么内容都没有了,你赶急 ...

  8. 我的第一个python web开发框架(38)——管理员管理功能

    后台管理员的管理功能,它主要用来管理后台的登录账号,绑定权限,当然如果想将后台管理扩展成企业相关管理系统,比如用于公司人事管理,在这个基础上进行适当扩展就可以了. 我们先看看界面效果(也可以看着数据字 ...

  9. 我的第一个python web开发框架(36)——后台菜单管理功能

    对于后台管理系统来说,要做好权限管理离不开菜单项和页面按钮控件功能的管理.由于程序没法智能的知道有什么菜单和控件,哪些人拥有哪些操作权限,所以首先要做的是菜单管理功能,将需要管理的菜单项和各个功能项添 ...

随机推荐

  1. 函数声明 和 var声明的优先级

    function demo() { console.log(5) } var demo = function(){ console.log(4) } console.log(demo()) var d ...

  2. python学习——读取染色体长度(七:读取fasta文件)

    读取fasta文件genome_test.fa,并计算染色体总长,同时输出最长染色体编号.序列以及长度 fasta文件genom_test.fa的内容如下: >chr1ATATATATAT> ...

  3. 有人WIFI模块使用详解

    补充 模块在连接路由器时如果希望模块固定IP 不过发现固定IP之后好像连接路由器的等待时间增加了 用的这一款 看一下现在可能用到了引脚 这个模块也有三种模式AP,STA,AP+STA 先说一下模块在A ...

  4. 【死磕 Spring】----- IOC 之 注册 BeanDefinition

    原文出自:http://cmsblogs.com 获取 Document 对象后,会根据该对象和 Resource 资源对象调用 registerBeanDefinitions() 方法,开始注册 B ...

  5. Python中星号的本质和使用方式

    翻译:Python 开发者 - 一汀, 英文:Trey Hunner http://blog.jobbole.com/114655/ Python开发者 在 Python 中有很多地方可以看到*和** ...

  6. python进程和线程(五)

    python的进程 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用的多进程包m ...

  7. 『集群』003 Slithice 最简分布式(多个客户端,一个独立服务端)

    Slithice 最简分布式(多个客户端,一个独立服务端) 案例Demo 展示: 我们搭建一个 可以 独立运行 的 服务端:然后 多个客户端 并发链接 这个 服务端 完成 分布式逻辑: 服务器 独立运 ...

  8. c#多线程总结(纯干货)

    线程基础 创建线程 static void Main(string[] args) { Thread t = new Thread(PrintNumbers); t.Start();//线程开始执行 ...

  9. Python编程从入门到实践笔记——if语句

    Python编程从入门到实践笔记——if语句 #coding=utf-8 cars=['bwm','audi','toyota','subaru','maserati'] bicycles = [&q ...

  10. Python使用Ctypes与C/C++ DLL文件通信过程介绍及实例分析

    项目中可能会经常用到第三方库,主要是出于程序效率考虑和节约开发时间避免重复造轮子.无论第三方库开源与否,编程语言是否与当前项目一致,我们最终的目的是在当前编程环境中调用库中的方法并得到结果或者借助库中 ...