帮助首页 > 网站操作说明 · 1. 系统后台操作说明 > 菜单权限 · 角色与公司等级(深度说明)

菜单权限 · 角色与公司等级(深度说明)

管理者、公司员工、项目员工、公司部门:权限与流程全面分析报告

代码基线:D:\www\baoan(ThinkPHP3.1)
报告目标:系统性说明四类主体的权限边界、添加流程、数据关系、相互联系与现状缺口。

1. 结论先看(摘要)

  • 公司管理者(店主):以 shop.user_id 为核心身份;进入 MerchantgetPermissionCodes() 对店主返回 *(全权限)。
  • 公司员工(shop_worker)

- 员工端:主入口为 Worker 模块(如 worker/index/index),菜单由 shop_worker.is_xxx 控制,大量操作通过链接进入 Distributors 子模块完成。

- 公司后台(Merchant/Distributors)并非只有店主能进。只要当前环境能解析出用户可操作的 shop_id(如 resolve_merchant_shop_for_uid($uid) 等),且该用户在 org_user_role 等 RBAC 中有授权,即可进入公司后台;菜单与按钮由 hasPermission(permission_code) 裁剪,与店主全开通形成差异。

  • 项目员工(project_worker):是“公司员工进入某个项目”的二级映射,项目内操作几乎都以 project_id + worker_id 验权。
  • 公司部门(org_*):RBAC 相关表已落地;Merchant 侧已提供部门、角色、人员授权、审计日志等控制器(需配合权限点 org.* 使用)。
  • 权限体系是“双轨”

- 轨道A:shop_worker.is_xxx(员工功能开关,偏业务能力,主要体现在 Worker 端与跳转 Distributors 的入口

- 轨道B:org_* RBAC(角色-权限点,偏组织权限,主要体现在 Merchant 端菜单与 requirePermission 动作

  • 关键现实问题:若运行环境提供 resolve_merchant_shop_for_uid / get_merchant_accessible_shops 等解析函数,Merchant/CommonAction 会退化为仅 Shop.user_id = 当前用户非店主员工仍无法进入 PC 公司后台——与“员工也应能进后台”的目标冲突,需保证 helper 部署一致或改造兜底逻辑。

2. 角色与数据模型

2.1 公司管理者(店主)

  • 核心表:shop
  • 核心字段:shop.user_id
  • 语义:该用户是公司主账号,默认拥有后台高权限(*
  • 入口控制:Merchant/CommonActionDistributors/CommonAction 初始化时解析当前公司

2.2 公司员工

  • 核心表:shop_worker
  • 关键字段:worker_id, shop_id, user_id, status, closed, is_*
  • 语义:员工属于某公司;业务能力主要由 is_* 控制(Worker/Distributors 入口);组织后台能力org_user_role 等 RBAC 控制(Merchant 入口,与店主全权限区分)
  • 扩展表:

- worker_qualification(个人资质)

- worker_achievement(工作业绩)

2.3 项目员工

  • 核心表:project_worker
  • 关键字段:id, project_id, worker_id, role(项目内角色,1 常见为管理)
  • 语义:把“公司员工”绑定到“项目”,形成项目维度权限与操作主体

2.4 公司部门

  • 设计表(迁移SQL已给出):org_department
  • 关键字段:dept_id, shop_id, parent_dept_id, dept_name, dept_code, dept_leader_user_id
  • 当前代码侧落地:Merchant 模块已提供 OrgdepartmentActionOrgroleActionOrguserroleActionOrgauditAction 等与 RBAC 配套的管理入口(具体菜单在 merchant/index/index.html 等公司后台菜单中挂载,受 hasPermission('org.xxx') 等控制)。

3. 权限体系总览

3.1 体系A:员工业务权限位(shop_worker.is_xxx

Merchant/WorkerAction 中写入并校验,典型字段:

  • is_photo, is_coupon, is_news, is_worker, is_dianping, is_job
  • is_tender, is_companycollect, is_shop, is_branch, is_project

特征:

  • 粒度是“功能模块开关”
  • 适合快速控制员工在各业务模块是否可见/可用
  • 常见于员工个人后台和公司后台员工配置页

3.2 体系B:组织 RBAC(org_*

已存在的数据结构:

  • org_department
  • org_role
  • org_permission
  • org_role_permission
  • org_user_role

已存在的权限点示例(迁移脚本):

  • legal.project.menu
  • legal.project.index/create/edit/detail/delete
  • org.department.manage, org.role.manage, org.user_role.manage

特征:

  • 粒度是“权限点(permission_code)”
  • 更适合管理者/部门/角色治理;在 Merchant 侧已通过 getPermissionCodes() + hasPermission() / requirePermission() 驱动菜单与动作
  • 落地约束主要在于:非店主能否解析到 shop_id(见第8章 resolve_merchant_shop_for_uid 部署一致性),以及 Distributors/WAP 与 Merchant 是否共用同一套 RBAC 展示策略

4. 添加流程(全链路)

4.1 公司员工添加流程(Merchant)

入口:Merchant/WorkerAction::create

流程:

  1. 提交 data(员工基础信息 + 权限位)
  2. 校验用户是否存在:Users.find(user_id)
  3. 校验是否已属其他公司 / 重复添加(基于 shop_worker
  4. 写入 shop_worker默认 status=1(直接生效,无需员工在会员中心再点同意)
  5. 写入资质 worker_qualification(可多条)
  6. 写入业绩 worker_achievement(可多条)
  7. 发系统消息通知员工(文案为已添加生效类提示,非“必须同意”)

结果:

  • 员工记录创建完成后立即可作为有效员工参与 member_visible_worker_entries_for_uid、Worker 端等逻辑(仍需公司 shop.audit=1 等条件,见会员中心员工入口实现)。

4.2 公司员工编辑流程(Merchant)

入口:Merchant/WorkerAction::edit

流程:

  1. 校验 worker_id 属于当前 shop_id
  2. 更新 shop_worker 基本信息与权限位
  3. 遍历 qualifications

- 有 qual_id + 有标题:更新

- 有 qual_id + 标题空:删除

- 无 qual_id + 有标题:新增

  1. 遍历 achievements 同样逻辑处理

4.3 项目员工添加流程(Distributors)

入口:Distributors/ProjectAction::addWorker

流程:

  1. 校验 project_idshop_id 归属
  2. 校验 worker_id 是当前公司员工
  3. 检查 project_id + worker_id 是否重复
  4. 写入 project_worker(含 role,并兼容扩展字段)

补充:

  • 项目员工可在 setting 中更新 role、排班时间、岗位等扩展信息
  • 删除项目员工走 removeWorker

4.4 公司部门添加流程(现状)

  • DB 设计层:有 org_department 表结构与索引
  • 业务层:Merchant/OrgdepartmentAction 等提供部门 CRUD、成员迁移与审计;与 org_roleorg_user_role、权限种子脚本配合使用
  • 结论:部门与 RBAC 已在 Merchant 侧形成主链路;Distributors 端是否镜像同等菜单取决于产品与路由配置

5. 相互关系(管理者-员工-项目-部门)

flowchart TD
    U[Users 会员]
    S[Shop 公司]
    SW[ShopWorker 公司员工]
    P[Project 项目]
    PW[ProjectWorker 项目员工]
    D[OrgDepartment 部门]
    R[OrgRole 角色]
    UR[OrgUserRole 用户角色]
    RP[OrgRolePermission]
    PM[OrgPermission]

    U -->|shop.user_id| S
    U -->|shop_worker.user_id| SW
    S -->|shop_id| SW
    S -->|shop_id| P
    SW -->|worker_id| PW
    P -->|project_id| PW

    S --> D
    S --> R
    U --> UR
    SW -->|可绑定 worker_id| UR
    D --> UR
    R --> UR
    R --> RP
    RP --> PM

关系解读:

  • “公司员工”是“项目员工”的前置集合
  • RBAC(部门/角色)与员工业务权限位可并行存在
  • 当前实现里,RBAC 与员工位权限并未完全统一成一套决策引擎

6. 实际权限判定路径

6.1 Merchant 侧

  • Merchant/CommonAction::getPermissionCodes()

- 店主:直接 *

- 非店主:查 org_user_role -> org_role_permission -> org_permission

  • hasPermission() 在菜单和动作中被调用(如项目、市场)

6.2 Project(Merchant)侧

  • Merchant/ProjectAction::requirePermission('legal.project.xxx')
  • 对项目增删改查进行 permission_code 级拦截

6.3 Worker(员工端)侧

  • 主要通过 Projectworker 绑定关系校验
  • 访问项目模块时统一检查:project_id + worker_id 是否存在
  • role 可区分项目管理者与普通成员(模板常用 is_manager = role == 1

7. 管理流程与联系图(业务视角)

  1. 管理者创建公司(或被认领绑定)
  2. 管理者添加公司员工,配置 is_xxx 权限位
  3. 员工添加后默认已生效(status=1);若历史数据仍为 status=0,会员中心“员工登录”等逻辑会不展示该身份
  4. 管理者在项目中分配员工(写入 project_worker
  5. 项目员工在 Worker 端执行门禁、巡检、考勤、日志、租户事务
  6. 若组织体系上线,可再叠加部门/角色/RBAC 做纵深权限治理

8. 现状问题与风险

  • 问题1:公司后台 shop 解析与 RBAC 进场

- Merchant/CommonAction 依赖 resolve_merchant_shop_for_uid($uid)(若存在)解析“当前公司”;否则兜底为 Shop.user_id = uid(仅店主)

- getPermissionCodes():店主 *;非店主依赖 org_user_role(含部门默认角色解析)拉取 permission_code

- 风险:生产环境若未部署 resolve_merchant_shop_for_uid,协作员工即使有 RBAC 也无法进入 Merchant,表现为“只有店主能进公司后台”

  • 问题2:权限双轨未统一

- shop_worker.is_xxxorg_permission 并存

- 部分模块走位权限,部分走 permission_code,维护成本高

  • 问题3:部门与 RBAC 的产品闭环仍不完整

- Merchant 侧已有部门/角色/授权/审计控制器,但 Distributors(手机公司端) 未必提供同等入口,用户容易误以为“部门只有表没有功能”

- “部门负责人—默认角色继承—员工授权”依赖 OrgDepartmentRoleResolveService 等与业务配置是否配齐;与 shop_worker.is_xxx 双轨并存时,运营解释成本高

  • 问题4:项目角色与公司角色割裂

- project_worker.role 与组织 org_role 尚未打通映射

- 项目内角色变更不自动反馈组织侧权限


9. 优化建议(按优先级)

P0(必须)

  • 统一“后台进场逻辑”并保证环境一致:

- 全环境部署 resolve_merchant_shop_for_uid(或等价解析),使非店主可基于 org_user_role 解析到 shop_id 后进入 Merchant

- 店主仍保留 * 超管能力;协作员工仅拥有已授予的 permission_code 集合

P1(高)

  • 建立权限决策中台:

- 统一封装 can($user, $shop, $permission_code, $module_flag)

- 在关键控制器统一调用,避免散落 if 判断

  • 对齐双轨:

- is_xxx 作为快速开关(UI/模块)

- permission_code 作为动作级校验(接口/按钮)

- 两者组合判定,形成可解释授权

P2(中)

  • 完善部门/RBAC 产品闭环:

- Merchant 已有能力基础上,评估是否在 Distributors 提供对称入口或只读视图

- 统一文档与培训:说明 is_xxxorg.* 的适用场景,降低双轨误配

  • 打通项目角色与组织角色:

- 例如 project_worker.role=1 自动映射某项目管理权限集合


10. 核对清单(可用于验收)

  • [ ] 公司管理者可正常进入 Merchant
  • [ ] 已配置 org_user_role 的协作员工在部署了 resolve_merchant_shop_for_uid 的环境下可进入 Merchant,且菜单与 hasPermission 一致
  • [ ] 公司员工可被添加、编辑、删除,资质/业绩可完整增删改
  • [ ] 项目员工可从公司员工池分配,且防重复分配
  • [ ] 项目员工在 Worker 端所有操作都受 project_worker 关系校验
  • [ ] 部门/角色/权限点可配置并对菜单与动作生效
  • [ ] 权限拒绝时有明确错误提示与审计记录

11. 关键代码与文档定位

  • Banyan/Lib/Action/Merchant/CommonAction.class.php
  • Banyan/Lib/Action/Merchant/WorkerAction.class.php
  • Banyan/Lib/Action/Merchant/ProjectAction.class.php
  • Banyan/Lib/Action/Distributors/ProjectAction.class.php
  • Banyan/Lib/Action/Worker/CommonAction.class.php
  • Banyan/Lib/Action/Worker/ProjectAction.class.php
  • Banyan/Lib/Model/ProjectworkerModel.class.php
  • docs/sql/migrations/V20260326_002_init_org_rbac.sql
  • docs/sql/migrations/V20260326_005_seed_permission_menu.sql

12. 三端对比:worker/index/index、公司后台、个人会员中心

下表便于区分 员工移动端门户公司管理后台个人会员中心 三者定位;同一 Users 账号可能同时具备多种身份(例如既是会员又是某店 shop_worker)。

维度个人会员中心(User)公司后台(Merchant / 部分 Distributors)员工端首页 themes/default/Worker/index/index.html
典型路由/模块user/member/...merchant/...(PC);distributors/...(WAP 公司端)worker/index/index(Worker 模块)
主要使用者任意注册用户店主 + 已授权协作员工(RBAC)已绑定 shop_worker 的员工
身份依据Users 登录态当前解析到的 shop_id + 店主或 org_user_roleshop_workeruser_idstatusclosed 等)
权限主要来源会员业务、订单、个人资料等getPermissionCodes():店主 *;否则 org_permission 代码集;动作上 requirePermission模板中大量 <if condition="$worker.is_xxx">;项目类能力另依赖 project_worker
与“公司”的关系可认领/绑定公司、查看“员工登录”入口等直接操作当前公司的配置、员工、项目、法务菜单等门户页:聚合验证、巡检、租户等入口;多数业务链通过链接进入 Distributors/*worker/project/*,而非在本页完成全部 CRUD
和本报告的关系个人侧展示“员工身份”依赖 member_visible_worker_entries_for_uid双轨中的 RBAC 轨主战场双轨中的 is_xxx主战场 + 项目绑定

一句话区分

  • 个人会员中心:以“自然人会员”为中心,不默认等于某公司后台。
  • 公司后台(Merchant):以“当前 shop_id 公司”为中心,店主与授权员工均可进入,差异在 hasPermission 可见菜单与可操作动作。
  • worker/index/index:面向已建档员工的 移动端工作台/验证中心,用 is_* 决定显示哪些模块入口,并常 跳转到 Distributors 子路径 完成具体业务;它不是 PC 公司后台的等价替换,而是员工日常操作的聚合入口。
copyright 2013-2113 www.baoanfuwu.cn All Rights Reserved 保安服务网版权所有
皖ICP备2021016109号-1