扩展AI助手功能,新增7个业务工具,涉及菜单管理、日志查询和数据分析

This commit is contained in:
geht
2026-04-03 12:11:28 +08:00
parent 60e2c8debd
commit f8f44c6b36

View File

@@ -18,6 +18,11 @@ import org.jeecg.modules.system.controller.SysUserController;
import org.jeecg.modules.system.entity.SysRole;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.jeecg.modules.system.entity.SysPermission;
import org.jeecg.modules.system.service.ISysPermissionService;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.system.entity.SysLog;
import org.jeecg.modules.system.service.ISysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -25,6 +30,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jeecg.common.util.DateUtils;
/**
* for [QQYUN-13565]【AI助手】新增创建用户和查询用户的工具扩展
@@ -50,6 +56,12 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
@Autowired
private org.jeecg.modules.system.service.ISysUserService sysUserService;
@Autowired
private ISysPermissionService sysPermissionService;
@Autowired
private ISysLogService sysLogService;
public Map<ToolSpecification, ToolExecutor> getDefaultTools(){
Map<ToolSpecification, ToolExecutor> tools = new HashMap<>();
JeecgLlmTools userTool = queryUserTool();
@@ -62,6 +74,27 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
// 新增:给用户授予角色
JeecgLlmTools grantRoles = grantUserRolesTool();
tools.put(grantRoles.getToolSpecification(), grantRoles.getToolExecutor());
// 新增:查询菜单
JeecgLlmTools queryMenus = queryMenusTool();
tools.put(queryMenus.getToolSpecification(), queryMenus.getToolExecutor());
// 新增:添加菜单
JeecgLlmTools addMenu = addMenuTool();
tools.put(addMenu.getToolSpecification(), addMenu.getToolExecutor());
// 新增:编辑菜单
JeecgLlmTools editMenu = editMenuTool();
tools.put(editMenu.getToolSpecification(), editMenu.getToolExecutor());
// 新增:删除菜单
JeecgLlmTools deleteMenu = deleteMenuTool();
tools.put(deleteMenu.getToolSpecification(), deleteMenu.getToolExecutor());
// 新增:查询系统日志
JeecgLlmTools queryLogs = queryLogsTool();
tools.put(queryLogs.getToolSpecification(), queryLogs.getToolExecutor());
// 新增:分析用户使用情况
JeecgLlmTools analyzeUserUsage = analyzeUserUsageTool();
tools.put(analyzeUserUsage.getToolSpecification(), analyzeUserUsage.getToolExecutor());
// 新增:分析操作情况
JeecgLlmTools analyzeOperations = analyzeOperationsTool();
tools.put(analyzeOperations.getToolSpecification(), analyzeOperations.getToolExecutor());
return tools;
}
@@ -267,4 +300,405 @@ public class JeecgBizToolsProvider implements JeecgToolsProvider {
};
return new JeecgLlmTools(spec, exec);
}
/**
* 查询菜单
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools queryMenusTool() {
ToolSpecification spec = ToolSpecification.builder()
.name("query_menus")
.description("查询菜单列表返回json数组。支持菜单名称、权限标识模糊查询无条件则返回全部菜单。")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("name", "菜单名称")
.addStringProperty("perms", "权限标识")
.build()
)
.build();
ToolExecutor exec = (toolExecutionRequest, memoryId) -> {
SysPermission sysPermission = JSONObject.parseObject(toolExecutionRequest.arguments(), SysPermission.class);
QueryWrapper<SysPermission> qw = Wrappers.query();
if (StringUtils.isNotBlank(sysPermission.getName())) {
qw.like("name", sysPermission.getName());
}
if (StringUtils.isNotBlank(sysPermission.getPerms())) {
qw.like("perms", sysPermission.getPerms());
}
qw.eq("del_flag", 0);
qw.orderByAsc("sort_no");
List<SysPermission> menus = sysPermissionService.list(qw);
return JSONObject.toJSONString(menus);
};
return new JeecgLlmTools(spec, exec);
}
/**
* 添加菜单
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools addMenuTool() {
ToolSpecification toolSpecification = ToolSpecification.builder()
.name("add_menu")
.description("添加菜单,返回添加结果;\n\n - 缺少必要字段时,请向用户索要.\n\n - 你应该提前判断用户的输入是否合法.\n\n - 添加成功后返回成功消息,如果失败则返回失败原因.")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("name", "菜单名称,必填")
.addStringProperty("parentId", "父菜单ID,必填")
.addStringProperty("menuType", "菜单类型,必填,0-目录,1-菜单,2-按钮")
.addStringProperty("url", "路由地址")
.addStringProperty("component", "组件路径")
.addStringProperty("perms", "权限标识")
.addNumberProperty("sortNo", "排序号")
.addStringProperty("icon", "图标")
.required("name", "parentId", "menuType")
.build()
)
.build();
ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
String msg = "添加菜单失败";
try {
SysPermission menu = JSON.parseObject(arguments.toJSONString(), SysPermission.class);
menu.setCreateTime(new Date());
menu.setDelFlag(CommonConstant.DEL_FLAG_0);
menu.setStatus("1");
sysPermissionService.addPermission(menu);
baseCommonService.addLog("添加菜单name " + menu.getName() ,CommonConstant.LOG_TYPE_2, 2);
msg = "添加菜单成功";
} catch (Exception e) {
e.printStackTrace();
msg = "添加菜单失败:" + e.getMessage();
}
return msg;
};
return new JeecgLlmTools(toolSpecification, toolExecutor);
}
/**
* 编辑菜单
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools editMenuTool() {
ToolSpecification toolSpecification = ToolSpecification.builder()
.name("edit_menu")
.description("编辑菜单,返回编辑结果;\n\n - 缺少必要字段时,请向用户索要.\n\n - 你应该提前判断用户的输入是否合法.\n\n - 编辑成功后返回成功消息,如果失败则返回失败原因.")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("id", "菜单ID,必填")
.addStringProperty("name", "菜单名称,必填")
.addStringProperty("parentId", "父菜单ID,必填")
.addStringProperty("menuType", "菜单类型,必填,0-目录,1-菜单,2-按钮")
.addStringProperty("url", "路由地址")
.addStringProperty("component", "组件路径")
.addStringProperty("perms", "权限标识")
.addNumberProperty("sortNo", "排序号")
.addStringProperty("icon", "图标")
.required("id", "name", "parentId", "menuType")
.build()
)
.build();
ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
String msg = "编辑菜单失败";
try {
SysPermission menu = JSON.parseObject(arguments.toJSONString(), SysPermission.class);
menu.setUpdateTime(new Date());
sysPermissionService.editPermission(menu);
baseCommonService.addLog("编辑菜单id " + menu.getId() ,CommonConstant.LOG_TYPE_2, 2);
msg = "编辑菜单成功";
} catch (Exception e) {
e.printStackTrace();
msg = "编辑菜单失败:" + e.getMessage();
}
return msg;
};
return new JeecgLlmTools(toolSpecification, toolExecutor);
}
/**
* 删除菜单
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools deleteMenuTool() {
ToolSpecification toolSpecification = ToolSpecification.builder()
.name("delete_menu")
.description("删除菜单,返回删除结果;\n\n - 缺少必要字段时,请向用户索要.\n\n - 删除成功后返回成功消息,如果失败则返回失败原因.")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("id", "菜单ID,必填")
.required("id")
.build()
)
.build();
ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
String menuId = arguments.getString("id");
String msg = "删除菜单失败";
try {
sysPermissionService.deletePermissionLogical(menuId);
baseCommonService.addLog("删除菜单id " + menuId ,CommonConstant.LOG_TYPE_2, 2);
msg = "删除菜单成功";
} catch (Exception e) {
e.printStackTrace();
msg = "删除菜单失败:" + e.getMessage();
}
return msg;
};
return new JeecgLlmTools(toolSpecification, toolExecutor);
}
/**
* 查询系统日志
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools queryLogsTool() {
ToolSpecification spec = ToolSpecification.builder()
.name("query_system_logs")
.description("查询系统日志支持按时间范围、日志类型、操作类型、用户名等条件查询。返回json数组。")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("startTime", "开始时间格式yyyy-MM-dd HH:mm:ss")
.addStringProperty("endTime", "结束时间格式yyyy-MM-dd HH:mm:ss")
.addNumberProperty("logType", "日志类型1-登录日志2-操作日志")
.addNumberProperty("operateType", "操作类型1-查询2-添加3-修改4-删除5-导入6-导出")
.addStringProperty("username", "用户名")
.addStringProperty("logContent", "日志内容关键词")
.build()
)
.build();
ToolExecutor exec = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
QueryWrapper<SysLog> qw = Wrappers.query();
// 时间范围
String startTime = arguments.getString("startTime");
String endTime = arguments.getString("endTime");
if (StringUtils.isNotBlank(startTime)) {
try {
Date start = org.jeecg.common.util.DateUtils.parseDate(startTime, "yyyy-MM-dd HH:mm:ss");
qw.ge("create_time", start);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
if (StringUtils.isNotBlank(endTime)) {
try {
Date end = org.jeecg.common.util.DateUtils.parseDate(endTime, "yyyy-MM-dd HH:mm:ss");
qw.le("create_time", end);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
// 日志类型
Integer logType = arguments.getInteger("logType");
if (logType != null) {
qw.eq("log_type", logType);
}
// 操作类型
Integer operateType = arguments.getInteger("operateType");
if (operateType != null) {
qw.eq("operate_type", operateType);
}
// 用户名
String username = arguments.getString("username");
if (StringUtils.isNotBlank(username)) {
qw.like("username", username);
}
// 日志内容
String logContent = arguments.getString("logContent");
if (StringUtils.isNotBlank(logContent)) {
qw.like("log_content", logContent);
}
qw.orderByDesc("create_time");
List<SysLog> logs = sysLogService.list(qw);
return JSONObject.toJSONString(logs);
};
return new JeecgLlmTools(spec, exec);
}
/**
* 分析用户使用情况
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools analyzeUserUsageTool() {
ToolSpecification spec = ToolSpecification.builder()
.name("analyze_user_usage")
.description("分析用户使用情况,包括登录次数、操作频率、活跃时间等。支持按时间范围分析。")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("startTime", "开始时间格式yyyy-MM-dd")
.addStringProperty("endTime", "结束时间格式yyyy-MM-dd")
.build()
)
.build();
ToolExecutor exec = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
QueryWrapper<SysLog> qw = Wrappers.query();
// 时间范围
String startTime = arguments.getString("startTime");
String endTime = arguments.getString("endTime");
if (StringUtils.isNotBlank(startTime)) {
try {
Date start = org.jeecg.common.util.DateUtils.parseDate(startTime + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
qw.ge("create_time", start);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
if (StringUtils.isNotBlank(endTime)) {
try {
Date end = org.jeecg.common.util.DateUtils.parseDate(endTime + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
qw.le("create_time", end);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
List<SysLog> logs = sysLogService.list(qw);
// 分析用户使用情况
Map<String, Map<String, Object>> userAnalysis = new HashMap<>();
for (SysLog log : logs) {
String username = log.getUsername();
if (StringUtils.isBlank(username)) continue;
if (!userAnalysis.containsKey(username)) {
Map<String, Object> userData = new HashMap<>();
userData.put("loginCount", 0);
userData.put("operationCount", 0);
userData.put("firstLogin", null);
userData.put("lastLogin", null);
userAnalysis.put(username, userData);
}
Map<String, Object> userData = userAnalysis.get(username);
// 登录日志
if (log.getLogType() != null && log.getLogType() == 1) {
int loginCount = (int) userData.get("loginCount");
userData.put("loginCount", loginCount + 1);
// 首次登录
if (userData.get("firstLogin") == null) {
userData.put("firstLogin", log.getCreateTime());
}
// 最后登录
userData.put("lastLogin", log.getCreateTime());
}
// 操作日志
if (log.getLogType() != null && log.getLogType() == 2) {
int operationCount = (int) userData.get("operationCount");
userData.put("operationCount", operationCount + 1);
}
}
return JSONObject.toJSONString(userAnalysis);
};
return new JeecgLlmTools(spec, exec);
}
/**
* 分析操作情况
* @return
* @author system
* @date 2026-04-02
*/
private JeecgLlmTools analyzeOperationsTool() {
ToolSpecification spec = ToolSpecification.builder()
.name("analyze_operations")
.description("分析系统操作情况,包括操作类型分布、高频操作、操作趋势等。支持按时间范围分析。")
.parameters(
JsonObjectSchema.builder()
.addStringProperty("startTime", "开始时间格式yyyy-MM-dd")
.addStringProperty("endTime", "结束时间格式yyyy-MM-dd")
.build()
)
.build();
ToolExecutor exec = (toolExecutionRequest, memoryId) -> {
JSONObject arguments = JSONObject.parseObject(toolExecutionRequest.arguments());
QueryWrapper<SysLog> qw = Wrappers.query();
// 时间范围
String startTime = arguments.getString("startTime");
String endTime = arguments.getString("endTime");
if (StringUtils.isNotBlank(startTime)) {
try {
Date start = org.jeecg.common.util.DateUtils.parseDate(startTime + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
qw.ge("create_time", start);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
if (StringUtils.isNotBlank(endTime)) {
try {
Date end = org.jeecg.common.util.DateUtils.parseDate(endTime + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
qw.le("create_time", end);
} catch (Exception e) {
// 时间格式错误,忽略
}
}
List<SysLog> logs = sysLogService.list(qw);
// 分析操作情况
Map<String, Object> analysis = new HashMap<>();
// 操作类型分布
Map<Integer, Integer> operationTypeDistribution = new HashMap<>();
// 高频操作
Map<String, Integer> highFrequencyOperations = new HashMap<>();
// 每日操作趋势
Map<String, Integer> dailyOperationTrend = new HashMap<>();
for (SysLog log : logs) {
// 操作类型分布
Integer operateType = log.getOperateType();
if (operateType != null) {
operationTypeDistribution.put(operateType, operationTypeDistribution.getOrDefault(operateType, 0) + 1);
}
// 高频操作
String logContent = log.getLogContent();
if (StringUtils.isNotBlank(logContent)) {
highFrequencyOperations.put(logContent, highFrequencyOperations.getOrDefault(logContent, 0) + 1);
}
// 每日操作趋势
if (log.getCreateTime() != null) {
String date = org.jeecg.common.util.DateUtils.formatDate(log.getCreateTime(), "yyyy-MM-dd");
dailyOperationTrend.put(date, dailyOperationTrend.getOrDefault(date, 0) + 1);
}
}
analysis.put("operationTypeDistribution", operationTypeDistribution);
analysis.put("highFrequencyOperations", highFrequencyOperations);
analysis.put("dailyOperationTrend", dailyOperationTrend);
return JSONObject.toJSONString(analysis);
};
return new JeecgLlmTools(spec, exec);
}
}