在跑腿系统开发中,权限问题往往被低估。很多团队初期直接写死:

  • if (isAdmin)
  • if (isRider)
  • if (isMerchant)

短期能跑,长期一定崩。

真正成熟的系统必须具备:

  • 多角色支持
  • 多端隔离(用户端、骑手端、商户端、平台端)
  • 细粒度接口权限控制
  • 数据权限隔离
  • 支持后期扩展角色

这篇文章讲一套可扩展的 RBAC 权限模型落地方案,并配核心代码示例。
跑腿系统开发


一、权限模型设计思路

在跑腿系统中,常见角色包括:

  • 平台超级管理员
  • 城市运营管理员
  • 商户管理员
  • 骑手
  • 普通用户
  • 财务人员

如果写死在代码里,未来新增“城市代理”“区域经理”就会非常痛苦。

正确做法是采用:

RBAC(Role-Based Access Control)模型。

核心关系:

用户 → 角色 → 权限 → 资源


二、数据库模型设计

1. 用户表

CREATE TABLE sys_user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    password VARCHAR(255),
    status TINYINT,
    create_time DATETIME
);

2. 角色表

CREATE TABLE sys_role (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    role_name VARCHAR(100),
    role_code VARCHAR(50),
    description VARCHAR(255)
);

3. 权限表

CREATE TABLE sys_permission (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    permission_name VARCHAR(100),
    permission_code VARCHAR(100),
    type VARCHAR(20),  -- MENU / API / BUTTON
    path VARCHAR(255)
);

4. 关联关系表

CREATE TABLE sys_user_role (
    user_id BIGINT,
    role_id BIGINT
);

CREATE TABLE sys_role_permission (
    role_id BIGINT,
    permission_id BIGINT
);

这样实现:

  • 一个用户可以有多个角色
  • 一个角色可以拥有多个权限

完全解耦。


三、Spring Security 实现权限控制

1. 加载用户权限

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserService userService;

    @Override
    public UserDetails loadUserByUsername(String username) {

        SysUser user = userService.getByUsername(username);

        List<String> permissions = userService.getUserPermissions(user.getId());

        List<GrantedAuthority> authorities = permissions.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());

        return new org.springframework.security.core.userdetails.User(
                user.getUsername(),
                user.getPassword(),
                authorities
        );
    }
}

2. 接口权限控制

@PreAuthorize("hasAuthority('ORDER_CREATE')")
@PostMapping("/order/create")
public Result createOrder(@RequestBody CreateOrderRequest request) {
    return orderService.create(request);
}

权限代码存数据库:

ORDER_CREATE
ORDER_CANCEL
RIDER_ASSIGN
FINANCE_EXPORT

新增权限只需要:

  • 插入数据库
  • 给角色分配权限

不需要改业务代码。


四、数据权限控制设计(关键)

很多系统只做接口权限,却忽略数据权限。

例如:

城市管理员只能看到自己城市订单。
商户只能看到自己门店订单。
骑手只能看到自己的配送单。

如果不做数据隔离,会非常危险。


1. 增加组织字段

订单表增加:

ALTER TABLE orders ADD city_id BIGINT;
ALTER TABLE orders ADD merchant_id BIGINT;

2. 基于用户角色动态拼接查询条件

public QueryWrapper<Order> buildDataScope(QueryWrapper<Order> wrapper) {

    LoginUser loginUser = SecurityUtils.getLoginUser();

    if (loginUser.hasRole("CITY_ADMIN")) {
        wrapper.eq("city_id", loginUser.getCityId());
    }

    if (loginUser.hasRole("MERCHANT_ADMIN")) {
        wrapper.eq("merchant_id", loginUser.getMerchantId());
    }

    if (loginUser.hasRole("RIDER")) {
        wrapper.eq("rider_id", loginUser.getUserId());
    }

    return wrapper;
}

然后在查询时统一调用:

public List<Order> listOrders() {

    QueryWrapper<Order> wrapper = new QueryWrapper<>();
    buildDataScope(wrapper);

    return orderMapper.selectList(wrapper);
}

这样实现数据级别隔离。
跑腿系统开发


五、前端菜单权限控制

权限模型不仅控制接口,还应控制菜单展示。

返回用户权限集合:

[
  "ORDER_LIST",
  "ORDER_CREATE",
  "RIDER_MANAGE"
]

前端根据 permission_code 控制菜单渲染。

Vue 示例:

if (permissions.includes('RIDER_MANAGE')) {
    showRiderMenu = true
}

这样做到前后端统一权限控制。


六、支持多端角色隔离设计

跑腿系统通常包括:

  • 用户端
  • 骑手端
  • 商户端
  • 平台端

建议增加:

ALTER TABLE sys_role ADD client_type VARCHAR(20);

例如:

USER
RIDER
MERCHANT
ADMIN

登录时校验角色所属客户端,避免角色串用。


七、可扩展优化方向

当系统规模扩大,可以升级为:

  • 基于 JWT 的无状态权限校验
  • 引入缓存(Redis)存储权限集合
  • 引入数据权限表达式(如 Spring EL)
  • 支持动态角色模板(加盟城市自动生成角色)

跑腿系统开发

八、总结

跑腿系统开发中,权限控制不是简单判断身份,而是一整套架构设计。

成熟的权限模型必须做到:

角色可扩展
权限可配置
接口可精细控制
数据可隔离
多端可区分

如果一开始权限写死,后期增加“城市代理”“加盟商”“区域运营”时,系统会非常混乱。

架构设计的本质不是多复杂,而是可持续扩展。

跑腿系统真正能长期稳定运营的基础,不是调度算法,而是权限与数据边界清晰。

这一点,很多团队都是踩过坑之后才明白。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐