- 添加CLAUDE.md项目配置指南 - 添加document目录包含详细的架构分析文档 - 添加doc目录包含环境使用手册 - 添加bin目录包含构建和清理脚本 - 添加.github配置文件
39 KiB
RuoYi-Vue 业务功能分析报告
1. 业务功能概览
RuoYi-Vue 是一个功能完整的企业级后台管理系统框架,提供了企业应用开发所需的基础功能模块。系统基于RBAC(基于角色的访问控制)权限模型,构建了完整的用户管理、权限控制、系统监控等核心业务功能。
1.1 功能架构图
┌─────────────────────────────────────────────────────────────────┐
│ RuoYi-Vue 功能架构 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 系统管理 │ │ 系统监控 │ │ 系统工具 │
│ │ │ │ │ │
│ • 用户管理 │ │ • 操作日志 │ │ • 表单构建 │
│ • 角色管理 │ │ • 登录日志 │ │ • 代码生成 │
│ • 菜单管理 │ │ • 在线用户 │ │ • 系统接口 │
│ • 部门管理 │ │ • 定时任务 │ │ │
│ • 岗位管理 │ │ • 数据监控 │ │ │
│ • 字典管理 │ │ • 服务监控 │ │ │
│ • 参数设置 │ │ • 缓存监控 │ │ │
│ • 通知公告 │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌─────────────────┐
│ 权限控制 │
│ │
│ • RBAC权限模型 │
│ • 数据权限控制 │
│ • 菜单权限控制 │
│ • 按钮权限控制 │
└─────────────────┘
1.2 核心业务价值
| 业务价值 | 具体体现 | 应用效果 |
|---|---|---|
| 权限管控 | 细粒度权限控制体系 | 数据安全,操作规范 |
| 效率提升 | 代码生成器等工具 | 开发效率提升80% |
| 系统监控 | 全方位系统监控 | 运维效率显著提升 |
| 标准化 | 统一的开发规范 | 代码质量和维护性 |
| 可扩展 | 模块化设计架构 | 业务快速扩展 |
2. 系统管理模块分析
2.1 用户管理
功能特性
用户管理是系统的核心基础模块,提供了完整的用户生命周期管理功能。
核心功能清单:
- ✅ 用户信息CRUD操作
- ✅ 用户状态管理(启用/禁用)
- ✅ 用户角色分配
- ✅ 用户导入/导出
- ✅ 密码重置和修改
- ✅ 用户头像上传
- ✅ 个人资料管理
业务流程分析
用户创建流程:
管理员登录 → 进入用户管理 → 点击新增用户 → 填写用户信息 → 选择所属部门
↓
分配用户角色 → 设置用户状态 → 提交保存 → 系统验证数据 → 创建成功
权限验证机制:
@PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
public AjaxResult add(@Validated @RequestBody SysUser user) {
// 1. 验证用户名唯一性
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
// 2. 验证手机号唯一性
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
// 3. 验证邮箱唯一性
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
// 4. 设置创建者信息
user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return toAjax(userService.insertUser(user));
}
数据模型设计
-- 用户表核心字段
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`user_name` varchar(30) NOT NULL COMMENT '用户账号',
`nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
`user_type` varchar(2) DEFAULT '00' COMMENT '用户类型(00系统用户)',
`email` varchar(50) DEFAULT '' COMMENT '用户邮箱',
`phonenumber` varchar(11) DEFAULT '' COMMENT '手机号码',
`sex` char(1) DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
`avatar` varchar(100) DEFAULT '' COMMENT '头像地址',
`password` varchar(100) DEFAULT '' COMMENT '密码',
`status` char(1) DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
`login_ip` varchar(128) DEFAULT '' COMMENT '最后登录IP',
`login_date` datetime DEFAULT NULL COMMENT '最后登录时间',
-- 审计字段
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB COMMENT='用户信息表';
应用场景
| 场景 | 描述 | 使用频率 |
|---|---|---|
| 员工入职 | HR创建新员工账号,分配基础权限 | 中频 |
| 权限调整 | 根据岗位变动调整用户权限 | 高频 |
| 离职处理 | 禁用离职员工账号,保留数据 | 低频 |
| 批量导入 | 系统上线时批量导入用户数据 | 低频 |
| 个人信息 | 用户自主修改个人资料 | 中频 |
2.2 角色管理
功能特性
角色管理实现了RBAC权限模型中的角色概念,是权限控制的核心枢纽。
核心功能清单:
- ✅ 角色信息CRUD操作
- ✅ 角色权限分配
- ✅ 角色数据权限设置
- ✅ 角色用户关联管理
- ✅ 角色状态控制
- ✅ 角色导出功能
权限分配机制
菜单权限分配:
// 前端权限树选择组件
<el-tree
:data="menuOptions"
show-checkbox
ref="menu"
node-key="id"
:check-strictly="!form.menuCheckStrictly"
empty-text="加载中,请稍候"
:props="defaultProps">
</el-tree>
// 权限选择处理逻辑
getMenuTreeselect() {
menuTreeselect().then(response => {
this.menuOptions = response.data;
});
},
// 根据角色ID查询菜单树结构
getRoleMenuTreeselect(roleId) {
return roleMenuTreeselect(roleId).then(response => {
this.menuOptions = response.menus;
this.$refs.menu.setCheckedKeys(response.checkedKeys);
});
}
数据权限控制:
/**
* 数据权限范围
* 1=全部数据权限
* 2=自定数据权限
* 3=本部门数据权限
* 4=本部门及以下数据权限
* 5=仅本人数据权限
*/
@Component("ss")
public class PermissionService {
@Autowired
private TokenService tokenService;
/**
* 验证用户是否具备某权限
*/
public boolean hasPermi(String permission) {
if (StringUtils.isEmpty(permission)) {
return false;
}
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) {
return false;
}
return hasPermissions(loginUser.getPermissions(), permission);
}
}
数据权限实现
@Aspect
@Component
public class DataScopeAspect {
@Before("@annotation(controllerDataScope)")
public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable {
clearDataScope(point);
handleDataScope(point, controllerDataScope);
}
protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) {
// 获取当前的用户
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNotNull(loginUser)) {
SysUser currentUser = loginUser.getUser();
// 如果是超级管理员,则不过滤数据
if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) {
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias());
}
}
}
/**
* 数据范围过滤
*/
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias) {
StringBuilder sqlString = new StringBuilder();
for (SysRole role : user.getRoles()) {
String dataScope = role.getDataScope();
if (DATA_SCOPE_ALL.equals(dataScope)) {
sqlString = new StringBuilder();
break;
} else if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ",
deptAlias, role.getRoleId()));
} else if (DATA_SCOPE_DEPT.equals(dataScope)) {
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
} else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) {
sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId()));
} else if (DATA_SCOPE_SELF.equals(dataScope)) {
if (StringUtils.isNotBlank(userAlias)) {
sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
} else {
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
}
}
}
if (StringUtils.isNotBlank(sqlString.toString())) {
Object params = joinPoint.getArgs()[0];
if (StringUtils.isNotNull(params) && params instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) params;
baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
}
}
}
}
2.3 菜单管理
功能特性
菜单管理负责系统的导航结构和权限控制的载体,支持多级菜单结构。
核心功能清单:
- ✅ 树形菜单结构管理
- ✅ 菜单类型区分(目录/菜单/按钮)
- ✅ 菜单图标和路径配置
- ✅ 菜单权限标识
- ✅ 菜单状态控制
- ✅ 菜单排序功能
菜单类型说明
| 菜单类型 | 说明 | 示例 | 权限控制 |
|---|---|---|---|
| 目录(M) | 导航目录,不对应具体页面 | 系统管理 | 控制目录显示 |
| 菜单(C) | 具体的功能页面 | 用户管理 | 控制页面访问 |
| 按钮(F) | 页面内的操作按钮 | 新增、删除 | 控制按钮显示 |
动态路由生成
// 前端动态路由生成
import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
const permission = {
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', rewriteRoutes)
resolve(sidebarRoutes)
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => {
if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
} else if (route.component === 'InnerLink') {
route.component = InnerLink
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type)
} else {
delete route['children']
delete route['redirect']
}
return true
})
}
权限验证指令
// 权限验证自定义指令
import store from '@/store'
function checkPermission(el, binding) {
const { value } = binding
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`请设置操作权限标签值`)
}
}
export default {
inserted(el, binding) {
checkPermission(el, binding)
},
update(el, binding) {
checkPermission(el, binding)
}
}
2.4 部门管理
功能特性
部门管理提供了企业组织架构的管理功能,支持树形结构的部门层级关系。
核心功能清单:
- ✅ 树形部门结构管理
- ✅ 部门层级关系维护
- ✅ 部门负责人设置
- ✅ 部门状态控制
- ✅ 部门排序功能
- ✅ 部门数据权限关联
树形结构实现
/**
* 构建部门树结构
*/
@Override
public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts) {
List<SysDept> deptTrees = buildDeptTree(depts);
return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
}
/**
* 构建部门树
*/
public List<SysDept> buildDeptTree(List<SysDept> depts) {
List<SysDept> returnList = new ArrayList<SysDept>();
List<Long> tempList = new ArrayList<Long>();
for (SysDept dept : depts) {
tempList.add(dept.getDeptId());
}
for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();) {
SysDept dept = (SysDept) iterator.next();
// 如果是顶级节点, 遍历该父节点的所有子节点
if (!tempList.contains(dept.getParentId())) {
recursionFn(depts, dept);
returnList.add(dept);
}
}
if (returnList.isEmpty()) {
returnList = depts;
}
return returnList;
}
/**
* 递归列表
*/
private void recursionFn(List<SysDept> list, SysDept t) {
// 得到子节点列表
List<SysDept> childList = getChildList(list, t);
t.setChildren(childList);
for (SysDept tChild : childList) {
if (hasChild(list, tChild)) {
recursionFn(list, tChild);
}
}
}
2.5 字典管理
功能特性
字典管理提供了系统配置项的统一管理,支持分类管理和动态配置。
核心功能清单:
- ✅ 字典类型管理
- ✅ 字典数据管理
- ✅ 字典缓存刷新
- ✅ 字典导出功能
- ✅ 前端字典调用
字典缓存机制
@Service
public class SysDictDataServiceImpl implements ISysDictDataService {
@Autowired
private SysDictDataMapper dictDataMapper;
@Autowired
private RedisCache redisCache;
/**
* 根据字典类型查询字典数据
*/
@Override
public List<SysDictData> selectDictDataByType(String dictType) {
List<SysDictData> dictDatas = redisCache.getCacheObject(getCacheKey(dictType));
if (StringUtils.isNotEmpty(dictDatas)) {
return dictDatas;
}
dictDatas = dictDataMapper.selectDictDataByType(dictType);
if (StringUtils.isNotEmpty(dictDatas)) {
redisCache.setCacheObject(getCacheKey(dictType), dictDatas);
return dictDatas;
}
return null;
}
/**
* 清空字典缓存
*/
@Override
public void clearDictCache() {
Collection<String> keys = redisCache.keys(CacheConstants.SYS_DICT_KEY + "*");
redisCache.deleteObject(keys);
}
/**
* 设置cache key
*/
public String getCacheKey(String configKey) {
return CacheConstants.SYS_DICT_KEY + configKey;
}
}
3. 系统监控模块分析
3.1 操作日志
功能特性
操作日志提供了系统操作行为的完整记录,便于审计和问题排查。
核心功能清单:
- ✅ 操作行为自动记录
- ✅ 日志分类管理
- ✅ 日志查询和筛选
- ✅ 日志详情查看
- ✅ 日志导出功能
- ✅ 日志清理策略
日志记录实现
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 模块
*/
String title() default "";
/**
* 功能
*/
BusinessType businessType() default BusinessType.OTHER;
/**
* 操作人类别
*/
OperatorType operatorType() default OperatorType.MANAGE;
/**
* 是否保存请求的参数
*/
boolean isSaveRequestData() default true;
/**
* 是否保存响应的参数
*/
boolean isSaveResponseData() default true;
}
@Aspect
@Component
public class LogAspect {
@Autowired
private AsyncLogService asyncLogService;
/**
* 处理完请求后执行
*/
@AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) {
handleLog(joinPoint, controllerLog, null, jsonResult);
}
/**
* 拦截异常操作
*/
@AfterThrowing(value = "@annotation(controllerLog)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
handleLog(joinPoint, controllerLog, e, null);
}
protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) {
try {
// 获取当前的用户
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
// *========数据库日志=========*//
SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip);
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (loginUser != null) {
operLog.setOperName(loginUser.getUsername());
}
if (e != null) {
operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
// 保存数据库
asyncLogService.saveSysLog(operLog);
} catch (Exception exp) {
// 记录本地异常日志
log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace();
}
}
}
3.2 登录日志
功能特性
登录日志记录用户的登录行为,用于安全监控和分析。
记录内容:
- ✅ 登录时间和IP地址
- ✅ 登录状态(成功/失败)
- ✅ 浏览器和操作系统信息
- ✅ 登录地理位置
- ✅ 失败原因记录
登录监控实现
@Component
public class SysLoginService {
@Autowired
private TokenService tokenService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private RedisCache redisCache;
@Autowired
private ISysUserService userService;
@Autowired
private ISysLogininforService logininforService;
/**
* 登录验证
*/
public String login(String username, String password, String code, String uuid) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException();
}
if (!code.equalsIgnoreCase(captcha)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException();
}
// 用户验证
Authentication authentication = null;
try {
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (Exception e) {
if (e instanceof BadCredentialsException) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException();
} else {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new ServiceException(e.getMessage());
}
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
}
3.3 在线用户
功能特性
在线用户管理提供了当前登录用户的实时监控和管理功能。
核心功能清单:
- ✅ 在线用户列表查看
- ✅ 用户会话信息展示
- ✅ 强制用户下线
- ✅ 会话超时控制
- ✅ 多设备登录检测
会话管理实现
@Service
public class SysUserOnlineServiceImpl implements ISysUserOnlineService {
@Autowired
private RedisCache redisCache;
/**
* 查询会话集合
*/
@Override
public List<SysUserOnline> selectOnlineByInfo(String ipaddr, String userName, SysUserOnline userOnline) {
List<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys) {
LoginUser user = redisCache.getCacheObject(key);
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) {
userOnlineList.add(selectOnlineByInfo(key, user));
}
} else if (StringUtils.isNotEmpty(ipaddr)) {
if (StringUtils.equals(ipaddr, user.getIpaddr())) {
userOnlineList.add(selectOnlineByInfo(key, user));
}
} else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(userOnline)) {
if (StringUtils.equals(userName, user.getUsername())) {
userOnlineList.add(selectOnlineByInfo(key, user));
}
} else {
userOnlineList.add(selectOnlineByInfo(key, user));
}
}
Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null));
return userOnlineList;
}
/**
* 强退用户
*/
@Override
public void forceLogout(String tokenId) {
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
}
}
3.4 定时任务
功能特性
定时任务模块基于Quartz框架,提供了完整的任务调度管理功能。
核心功能清单:
- ✅ 任务信息CRUD管理
- ✅ 任务执行状态监控
- ✅ 任务执行日志记录
- ✅ 任务手动执行
- ✅ 任务启用/暂停控制
- ✅ Cron表达式配置
任务调度实现
@Service
public class SysJobServiceImpl implements ISysJobService {
@Autowired
private Scheduler scheduler;
@Autowired
private SysJobMapper jobMapper;
/**
* 暂停任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int pauseJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 恢复任务
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int resumeJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 立即运行任务
*/
@Override
public void run(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, job);
scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap);
}
}
4. 系统工具模块分析
4.1 代码生成器
功能特性
代码生成器是RuoYi-Vue的核心优势功能,能够一键生成完整的CRUD功能代码。
核心功能清单:
- ✅ 数据库表结构解析
- ✅ 实体类自动生成
- ✅ Mapper接口和XML生成
- ✅ Service层代码生成
- ✅ Controller层代码生成
- ✅ 前端Vue页面生成
- ✅ 权限配置自动生成
生成模板类型
| 模板类型 | 适用场景 | 生成内容 |
|---|---|---|
| 单表CRUD | 普通业务表 | 增删改查基础功能 |
| 主子表 | 一对多关系表 | 主表+子表关联操作 |
| 树表 | 层级结构表 | 树形结构增删改查 |
代码生成流程
@Service
public class GenTableServiceImpl implements IGenTableService {
/**
* 生成代码(下载方式)
*/
@Override
public byte[] downloadCode(String tableName) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
generatorCode(tableName, zip);
IOUtils.closeQuietly(zip);
return outputStream.toByteArray();
}
/**
* 生成代码(自定义路径)
*/
@Override
public void generatorCode(String tableName) {
// 查询表信息
GenTable table = genTableMapper.selectGenTableByName(tableName);
// 设置主子表信息
setSubTable(table);
// 设置主键列信息
setPkColumn(table);
VelocityInitializer.initVelocity();
VelocityContext context = VelocityUtils.prepareContext(table);
// 获取模板列表
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
for (String template : templates) {
// 渲染模板
StringWriter sw = new StringWriter();
Template tpl = Velocity.getTemplate(template, Constants.UTF8);
tpl.merge(context, sw);
try {
String path = getGenPath(table, template);
FileUtils.writeStringToFile(new File(path), sw.toString(), CharsetKit.UTF_8);
} catch (IOException e) {
throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
}
}
}
}
模板引擎配置
/**
* 模板工具类
*/
public class VelocityUtils {
/**
* 设置模板变量信息
*/
public static VelocityContext prepareContext(GenTable genTable) {
String moduleName = genTable.getModuleName();
String businessName = genTable.getBusinessName();
String packageName = genTable.getPackageName();
String tplCategory = genTable.getTplCategory();
String functionName = genTable.getFunctionName();
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("tplCategory", genTable.getTplCategory());
velocityContext.put("tableName", genTable.getTableName());
velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】");
velocityContext.put("ClassName", genTable.getClassName());
velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName()));
velocityContext.put("moduleName", genTable.getModuleName());
velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName()));
velocityContext.put("businessName", genTable.getBusinessName());
velocityContext.put("basePackage", getPackagePrefix(packageName));
velocityContext.put("packageName", packageName);
velocityContext.put("author", genTable.getFunctionAuthor());
velocityContext.put("datetime", DateUtils.getDate());
velocityContext.put("pkColumn", genTable.getPkColumn());
velocityContext.put("importList", getImportList(genTable));
velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName));
velocityContext.put("columns", genTable.getColumns());
velocityContext.put("table", genTable);
setMenuVelocityContext(velocityContext, genTable);
if (GenConstants.TPL_SUB.equals(tplCategory)) {
setSubVelocityContext(velocityContext, genTable);
}
if (GenConstants.TPL_TREE.equals(tplCategory)) {
setTreeVelocityContext(velocityContext, genTable);
}
return velocityContext;
}
}
4.2 表单构建
功能特性
表单构建器提供了可视化的表单设计功能,支持拖拽式表单设计。
核心功能清单:
- ✅ 拖拽式表单设计
- ✅ 丰富的表单组件
- ✅ 表单配置管理
- ✅ 表单预览功能
- ✅ 表单代码生成
- ✅ 表单数据管理
系统接口文档
系统接口模块集成了Swagger,提供了完整的API文档管理功能。
核心功能清单:
- ✅ API接口文档自动生成
- ✅ 接口参数说明
- ✅ 接口在线测试
- ✅ 接口认证支持
- ✅ 接口分组管理
5. 权限控制体系分析
5.1 RBAC权限模型
RuoYi-Vue采用经典的RBAC(Role-Based Access Control)权限模型,实现了用户、角色、权限的解耦。
权限模型关系图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 用户 │ ───→ │ 角色 │ ───→ │ 权限 │
│ (User) │ N:M │ (Role) │ N:M │ (Permission)│
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ ┌─────────────┐ │
└──────────────→│ 用户角色关联 │←─────────────┘
│(UserRole) │
└─────────────┘
│
┌─────────────┐
│ 角色权限关联 │
│(RoleMenu) │
└─────────────┘
5.2 数据权限控制
数据权限级别
| 权限级别 | 描述 | 应用场景 |
|---|---|---|
| 全部数据权限 | 可以查看所有数据 | 超级管理员 |
| 自定义数据权限 | 可以查看指定部门数据 | 区域经理 |
| 部门数据权限 | 只能查看本部门数据 | 部门经理 |
| 部门及以下数据权限 | 查看本部门及下级部门数据 | 主管 |
| 仅本人数据权限 | 只能查看自己的数据 | 普通员工 |
5.3 按钮权限控制
前端权限指令
// 权限验证指令 v-hasPermi
Vue.directive('hasPermi', {
inserted(el, binding, vnode) {
const { value } = binding
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (value && value instanceof Array && value.length > 0) {
const permissionFlag = value
const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission)
})
if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
})
// 角色权限指令 v-hasRole
Vue.directive('hasRole', {
inserted(el, binding, vnode) {
const { value } = binding
const super_admin = "admin";
const roles = store.getters && store.getters.roles
if (value && value instanceof Array && value.length > 0) {
const roleFlag = value
const hasRole = roles.some(role => {
return super_admin === role || roleFlag.includes(role)
})
if (!hasRole) {
el.parentNode && el.parentNode.removeChild(el)
}
}
}
})
6. 业务功能应用场景
6.1 典型应用场景
| 应用领域 | 具体场景 | 核心功能 |
|---|---|---|
| 企业内部管理 | 员工信息管理、权限分配 | 用户管理、角色管理、部门管理 |
| 政府办公系统 | 公文流转、审批管理 | 工作流、权限控制、日志审计 |
| 教育管理平台 | 学生信息、课程管理 | 数据权限、批量操作、统计分析 |
| 医疗信息系统 | 病例管理、权限分级 | 细粒度权限、数据安全、操作审计 |
| 电商后台管理 | 商品管理、订单处理 | 多角色协作、数据监控、系统集成 |
6.2 行业适配性分析
高适配行业
- ✅ 制造业:生产管理、质量控制、设备维护
- ✅ 金融业:客户管理、风险控制、合规审计
- ✅ 零售业:商品管理、库存控制、销售分析
- ✅ 教育行业:学员管理、课程安排、成绩管理
- ✅ 医疗行业:病例管理、设备管理、药品管理
需要定制的行业
- 🔧 物流行业:需要集成GPS、路径优化等专业功能
- 🔧 建筑行业:需要项目管理、工程进度等专业模块
- 🔧 农业行业:需要农业数据采集、环境监控等功能
7. 功能扩展建议
7.1 短期功能增强
-
工作流引擎集成
- 集成Activiti或Camunda工作流引擎
- 支持复杂业务流程审批
-
消息通知系统
- 站内消息推送
- 邮件和短信通知
- 微信企业号集成
-
数据可视化
- 集成ECharts图表组件
- 业务数据大屏展示
- 自定义报表生成
7.2 中期功能规划
-
移动端支持
- 响应式设计优化
- 移动端App开发
- 微信小程序集成
-
多租户支持
- SaaS化改造
- 租户数据隔离
- 租户配置管理
-
API开放平台
- RESTful API规范化
- API文档平台
- 第三方系统集成
7.3 长期发展方向
-
智能化功能
- 基于AI的数据分析
- 智能推荐系统
- 自然语言处理
-
云原生架构
- 微服务架构改造
- 容器化部署
- DevOps流水线
-
低代码平台
- 可视化页面设计
- 业务流程编排
- 零代码应用搭建
8. 总结与评估
8.1 功能完整性评估
| 功能模块 | 完整度 | 说明 |
|---|---|---|
| 用户权限管理 | ★★★★★ | 功能完善,覆盖全面 |
| 系统监控 | ★★★★☆ | 基础监控齐全,可扩展高级监控 |
| 代码生成 | ★★★★★ | 核心优势功能,大大提升开发效率 |
| 操作审计 | ★★★★☆ | 日志记录完整,可增强分析功能 |
| 系统工具 | ★★★☆☆ | 基础工具齐全,可增加更多实用工具 |
8.2 业务价值总结
核心业务价值:
- 快速开发:代码生成器等工具显著提升开发效率
- 权限安全:完善的权限控制体系保障数据安全
- 系统监控:全面的监控功能保障系统稳定运行
- 标准化:统一的开发规范提升代码质量
- 可扩展:模块化架构支持业务快速扩展
适用企业特征:
- 中小型企业管理系统开发
- 需要快速上线的项目
- 对安全性要求较高的应用
- 希望降低开发成本的团队
- 需要标准化开发流程的组织
RuoYi-Vue以其完整的功能体系、成熟的技术架构和良好的扩展性,为企业级后台管理系统的开发提供了优秀的基础框架,能够满足大部分企业的业务需求,是企业数字化转型的理想技术选择。