当前位置: 首页 > news >正文

VFP权限管理怎么做?用户模式vs角色组模式,一看就懂

做VFP项目,权限管理是绕不过的坎。10个用户以内还好,一个个配权限就行。50个用户呢?100个呢?每次来新人都要一个一个菜单勾权限,配置到怀疑人生。

今天我们聊聊VFP权限管理的两种模式——用户模式和角色组模式,从设计到代码一次性讲清楚。


一、核心原理:利用菜单的Skip属性

VFP菜单有个属性叫跳过(Skip),可以控制菜单项是否可用。祺佑框架的权限设计就是基于这个简单而强大的机制。

需要三张表

表名

用途

user_pass

用户表(账号、密码等)

Rights

菜单表(description对应菜单名)

RoleRight

权限表(用户/组 + 菜单ID + 是否启用)

💡 description相当于菜单设计器的提示(菜单名),但可以多个菜单名对应一个description。


二、用户模式:简单直接

思路:每个用户直接配置菜单权限,一人一套。

权限加载代码

TEXT TO lcSQLCmd NOSHOW TEXTMERGE select description, isnull(enabled, 0) enabled, userid from rights left join ( SELECT a1.userid, right_id, enabled FROM RoleRight inner join ( select id userid from user_pass where USER_PASS.id = 1 ) a1 on RoleRight.userid = a1.userid ) b1 on Rights.id = right_id ENDTEXT oDBSQLhelper = Newobject("MSSQLHelper", "MSSQLHelper.prg") If oDBSQLhelper.SQLQuery(lcSQLCmd, "main_menus") < 0 Messagebox(oDBSQLhelper.errmsg) Return.F. Endif

用了左连接是因为菜单表随时会增加,这样查询就会将新增菜单项也全部展现,防止找不到权限。

关键技巧:纵向记录变横向属性

* 表变成对象(纵向记录变横向属性,方便菜单权限控制) Select main_menus oMenus = Createobject("empty") Scan AddProperty(oMenus, Alltrim(description), enabled) Endscan AddProperty(_screen, "oMenus", oMenus) && 挂到_screen全局可用

这样_screen.oMenus.采购入库就是.T..F.,直接控制菜单的Skip属性。

用户模式优点:代码极少,简单高效。
用户模式缺点:人多时配置工作量巨大。


三、角色组模式:人多了就靠它

思路:把权限分配给"组",用户只需选择所属组,自动继承组权限。

数据表改动

user_pass表增加两个字段:

字段

类型

说明

u_lx

逻辑型

.T.=组,.F.=用户(默认.F.)

roleid

整型

所属组ID(默认0=没有所属组)

组和用户在同一个表里,用u_lx字段区分。用户可以设置所属组,但组不可以选所属组。

自联接查询用户和组

Set Multilocks On * 用户列表(自联接,显示用户所属组名) TEXT TO lcSQLCmd noshow select a1.u_name, isnull(b1.u_name, '') rolename, a1.roleid, a1.id, u_lx from user_pass a1 left join ( select id, u_name from user_pass where u_lx = 1 ) b1 on a1.roleid = b1.id ENDTEXT oDBSQLhelper = Newobject("MSSQLHelper", "MSSQLHelper.prg") If oDBSQLhelper.SQLQuery(lcSQLCmd, "user_pass") < 0 Messagebox(oDBSQLhelper.errmsg) Return.F. Endif CursorSetProp("Buffering", 5, "user_pass") && 设置为表缓冲

角色组合框设置

* 角色列表(追加空选项方便选择) TEXT TO lcSQLCmd NOSHOW textm SELECT 0 as id, '' as rolename union all SELECT id, u_name as rolename FROM user_pass WHERE u_lx = 1 ENDTEXT If oDBSQLhelper.SQLQuery(lcSQLCmd, "rolelist") < 0 Messagebox(oDBSQLhelper.errmsg) Return.F. Endif

关键业务逻辑

1. 组合框显示/隐藏

This.Visible = !user_pass.u_lx && 如果是组,组合框隐藏掉

2. 权限列表只读控制

* 用户没有所属组,可以编辑权限列表,否则只读 If user_pass.roleid == 0 IfInlist(Thisform.Opcode, 1, 2) This.ReadOnly = .F. This.column3.Enabled = .T. Else This.ReadOnly = .T. This.column3.Enabled = .F. Endif Else This.ReadOnly = .T. This.column3.Enabled = .F. Endif

3. 保存时更新roleid

Tableupdate(1, .T., "user_pass") && 保存缓冲表 * 与DAL_CA共享链接 oDBSQLhelper = Newobject("MSSQLHelper", "MSSQLHelper.prg", "", Thisform.Oca.Datasource) TEXT TO lcSQLCmd NOSHOW TEXTMERGE UPDATE user_pass SET roleid = ?user_pass.roleid WHERE id = ?user_pass.id ENDTEXT If oDBSQLhelper.ExecuteSQL(lcSQLCmd) < 0 Messagebox(Thisform.Oca.msg) Return Endif

四、前端加载权限:组优先

前端用户获取菜单权限的逻辑非常简单:

* 判定用户的roleid不为空,就使用roleid加载权限 * 否则使用用户id来加载权限 If !Empty(user_pass.roleid) nLoadId = user_pass.roleid && 用组ID加载 Else nLoadId = user_pass.id && 用用户ID加载 Endif

五、进阶:Qiyu_Right权限类

祺佑框架还提供了Qiyu_RightManage权限管理类,支持更精细的权限控制:

属性

说明

isAdd

新增权限

isEdit

编辑权限

isDel

删除权限

isCheck

审核权限

isDee

记账权限

isPrit

打印权限

isGd1/isGd2/isGd3

自定义权限

权限控制两层
1.控制界面控件的开闭— 表单控件的Enabled由权限属性决定
2.控制DAL层方法调用— DAL的Get/Add/Edit/Delete方法受isAdd/isEdit/isDel控制

子类示例

* 由父类派生一个权限操作类 Define Class QX_SJQX As Qiyu_RightManage Of Locfile("Qiyu_RightManager.prg") * 钩子方法 - 用户自定义 Procedure GetRightStatus This.isadd = .f. This.isedit = .f. This.isdel = .f. EndProc EndDefine * 在表单的Init方法中使用 Thisform.oright = Newobject("qx_sjqx", "qx_sjqx.prg") Thisform.RightRefresh() && 权限刷新 Thisform.oright.SetRightStatus(Thisform) && 继承父类方法

六、两种模式怎么选?

维度

用户模式

角色组模式

适合人数

≤10人

10人以上

配置工作量

每人一套权限

配好组,新人选组即可

灵活性

★★★★★ 个性定制

★★★ 组内统一

代码复杂度

简单

稍复杂(自联接+缓冲)

维护成本

人员变动需逐个调整

加组/改组权限即可

我的建议
- 小项目(内部几人用)→ 用户模式,够用就好
- 中大型项目 → 角色组模式,一劳永逸
- 可以先上用户模式,随时平滑升级到角色组模式(数据表结构兼容)


互动时间

你的VFP项目用的哪种权限模式?有没有踩过权限管理的坑?评论区聊聊!

觉得有用,点赞+收藏⭐ 下次开发权限直接抄作业!

http://www.jsqmd.com/news/883622/

相关文章:

  • HS2-HF Patch:3分钟解锁Honey Select 2完整游戏体验的技术指南
  • Unity URP下缺失的MipMap可视化?手把手教你用Rendering Debugger和自定义Shader搞定
  • AutoCAD字体缺失问题如何通过智能插件彻底解决?
  • 别再纠结了!用Unity做独立游戏,2D、2.5D还是3D?看完这篇帮你定方向
  • 基于ESP32-S3的USB有线键盘无线化改造方案
  • 技术指南:qobuz-dl无损音乐下载器架构解析与实战应用
  • 基于汽车中控锁电机与射频模块的DIY无线门锁实战指南
  • 3分钟掌握罗技鼠标宏:终极PUBG压枪解决方案
  • 温差发电驱动轻型电动车:热电模块与催化燃烧器的系统集成实践
  • 长期使用Taotoken Token Plan套餐带来的成本节约感受
  • 告别实景拍摄!用Skybox AI + Unity 2022快速生成VR项目概念场景(附完整API接入避坑指南)
  • 别急着重启!HBase启动报错ServerNotRunningYetException,先看这3个日志文件和5个关键配置
  • i茅台自动预约系统:告别手动抢购,5分钟搭建智能预约平台
  • BetterJoy:5分钟让你的任天堂Switch手柄变身Windows游戏利器 [特殊字符]
  • Joy-Con Toolkit技术深度解析:从硬件逆向到手柄控制的创新实现
  • DeepSeek化学式粘贴后变形如何修复?手慢无!90%博士踩坑的公式黑洞,被“AI导出鸭”一夜终结! - AI导出鸭
  • 解密FileSaver.js:前端文件下载的进阶实战技巧与跨浏览器解决方案
  • 洛雪音乐桌面版:一个开源音乐聚合播放器的现代化体验之旅
  • 终极网页保存指南:如何用SingleFile一键保存完整网页为单个HTML文件
  • 微信单向好友检测终极指南:免费工具WechatRealFriends完整使用教程
  • docker架构
  • 2026广州搬家公司推荐:5家高口碑正规搬家机构深度测评 - 生活服务
  • 告别手动抢茅台!智能预约系统让你轻松实现茅台自由
  • 如何用ImageGlass实现专业图像管理:90+格式支持的完整解决方案
  • 从原理到防御:手把手教你用Python模拟ZipCrypto加密,理解密码为何能被‘撞开’
  • CAJ转PDF终极指南:免费开源工具帮你轻松打破知网格式壁垒
  • ZonyLrcToolsX:你的智能歌词管家,一键下载四大平台歌词
  • 别再手动调相机了!用Cinemachine插件5分钟搞定Unity第三人称跟随镜头(含FreeLook Camera配置)
  • 【国家级等保2.0合规红线】:DeepSeek代码审计必须覆盖的11个AI特有攻击面(附GPT-4o交叉验证报告)
  • 告别Houdini!用UE5.2原生PCG框架,像搭积木一样复用你的关卡设计