跑腿系统开发权限控制模型与角色管理架构设计
在跑腿系统开发中,权限问题往往被低估。很多团队初期直接写死:
- 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)
- 支持动态角色模板(加盟城市自动生成角色)

八、总结
跑腿系统开发中,权限控制不是简单判断身份,而是一整套架构设计。
成熟的权限模型必须做到:
角色可扩展
权限可配置
接口可精细控制
数据可隔离
多端可区分
如果一开始权限写死,后期增加“城市代理”“加盟商”“区域运营”时,系统会非常混乱。
架构设计的本质不是多复杂,而是可持续扩展。
跑腿系统真正能长期稳定运营的基础,不是调度算法,而是权限与数据边界清晰。
这一点,很多团队都是踩过坑之后才明白。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)