diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java index 2dced97d6..859f8844c 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/annotation/Log.java @@ -1,7 +1,8 @@ package org.dromara.common.log.annotation; import org.dromara.common.log.enums.BusinessType; -import org.dromara.common.log.enums.OperatorType; +import org.dromara.common.log.enums.OperateChannel; +import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; @@ -14,20 +15,44 @@ import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log { + /** - * 模块 + * 模块【已废弃,请使用 module】 + * + * @deprecated 请使用 {@link #module()} */ + @Deprecated String title() default ""; /** - * 功能 + * 业务模块名称(必填,如:用户管理、订单管理) + */ + String module() default ""; + + /** + * 操作功能名称(必填,如:新增用户、导出订单) + */ + String name() default ""; + + /** + * 操作描述(备注) + */ + String remark() default ""; + + /** + * 标签(用于检索/分类) + */ + String[] tags() default {}; + + /** + * 业务类型(查询/新增/修改/删除/导入/导出等) */ BusinessType businessType() default BusinessType.OTHER; /** - * 操作人类别 + * 操作渠道:WEB / APP / MINI_APP / OPEN_API 等 */ - OperatorType operatorType() default OperatorType.MANAGE; + OperateChannel channel() default OperateChannel.WEB; /** * 是否保存请求的参数 @@ -39,7 +64,6 @@ public @interface Log { */ boolean isSaveResponseData() default true; - /** * 排除指定的请求参数 */ diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java index 171e97b0b..2847d2b8a 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/aspect/LogAspect.java @@ -4,6 +4,8 @@ import cn.hutool.core.lang.Dict; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.http.useragent.UserAgent; +import cn.hutool.http.useragent.UserAgentUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -48,7 +50,7 @@ public class LogAspect { /** * 在目标方法执行前启动耗时统计。 * - * @param joinPoint 切点 + * @param joinPoint 切点 * @param controllerLog 日志注解 */ @Before(value = "@annotation(controllerLog)") @@ -61,9 +63,9 @@ public class LogAspect { /** * 在目标方法正常返回后记录操作日志。 * - * @param joinPoint 切点 + * @param joinPoint 切点 * @param controllerLog 日志注解 - * @param jsonResult 返回结果 + * @param jsonResult 返回结果 */ @AfterReturning(pointcut = "@annotation(controllerLog)", returning = "jsonResult") public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object jsonResult) { @@ -73,9 +75,9 @@ public class LogAspect { /** * 在目标方法抛出异常后记录操作日志。 * - * @param joinPoint 切点 + * @param joinPoint 切点 * @param controllerLog 日志注解 - * @param e 异常 + * @param e 异常 */ @AfterThrowing(value = "@annotation(controllerLog)", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) { @@ -85,35 +87,42 @@ public class LogAspect { /** * 组装并发布操作日志事件。 * - * @param joinPoint 切点 + * @param joinPoint 切点 * @param controllerLog 日志注解 - * @param e 异常信息 - * @param jsonResult 返回结果 + * @param e 异常信息 + * @param jsonResult 返回结果 */ protected void handleLog(final JoinPoint joinPoint, Log controllerLog, final Exception e, Object jsonResult) { try { - // *========数据库日志=========*// OperLogEvent operLog = new OperLogEvent(); - operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); - // 请求的地址 - String ip = ServletUtils.getClientIP(); - operLog.setOperIp(ip); - operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255)); + LoginUser loginUser = LoginHelper.getLoginUser(); - operLog.setOperName(loginUser.getUsername()); + operLog.setUsername(loginUser.getUsername()); operLog.setDeptName(loginUser.getDeptName()); + operLog.setUserType(loginUser.getUserType()); + operLog.setDeviceType(loginUser.getDeviceType()); + + operLog.setOperIp(ServletUtils.getClientIP()); + HttpServletRequest request = ServletUtils.getRequest(); + operLog.setOperUrl(StringUtils.substring(request.getRequestURI(), 0, 255)); + UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent")); + operLog.setBrowser(userAgent.getBrowser().getName()); + operLog.setOs(userAgent.getOs().getName()); if (e != null) { operLog.setStatus(BusinessStatus.FAIL.ordinal()); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 3800)); + } else { + operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); } + // 设置方法名称 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); operLog.setMethod(className + "." + methodName + "()"); // 设置请求方式 - operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); + operLog.setRequestMethod(request.getMethod()); // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); // 设置消耗时间 @@ -133,19 +142,19 @@ public class LogAspect { /** * 获取注解中对方法的描述信息 用于Controller层注解 * - * @param joinPoint 切点 - * @param log 日志 - * @param operLog 操作日志 + * @param joinPoint 切点 + * @param log 日志 + * @param operLog 操作日志 * @param jsonResult 返回结果 * @throws Exception 异常 */ public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception { - // 设置action动作 - operLog.setBusinessType(log.businessType().ordinal()); - // 设置标题 - operLog.setTitle(log.title()); - // 设置操作人类别 - operLog.setOperatorType(log.operatorType().ordinal()); + operLog.setModule(StringUtils.isBlank(log.title()) ? log.module() : log.title()); + operLog.setName(log.name()); + operLog.setRemark(log.remark()); + operLog.setTags(JsonUtils.toJsonString(log.tags())); + operLog.setBusinessType(log.businessType().getCode()); + operLog.setChannel(log.channel().getCode()); // 是否需要保存request,参数和值 if (log.isSaveRequestData()) { // 获取参数的信息,传入到数据库中。 @@ -160,8 +169,8 @@ public class LogAspect { /** * 获取请求的参数,放到log中 * - * @param joinPoint 切点 - * @param operLog 操作日志 + * @param joinPoint 切点 + * @param operLog 操作日志 * @param excludeParamNames 排除参数名 * @throws Exception 异常 */ @@ -181,7 +190,7 @@ public class LogAspect { /** * 将方法参数序列化为日志字符串。 * - * @param paramsArray 参数数组 + * @param paramsArray 参数数组 * @param excludeParamNames 排除字段名 * @return 参数字符串 */ @@ -242,6 +251,6 @@ public class LogAspect { } } return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse - || o instanceof BindingResult; + || o instanceof BindingResult; } } diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java index 2d25ebbb6..11fccb39e 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/BusinessType.java @@ -1,58 +1,195 @@ package org.dromara.common.log.enums; +import lombok.AllArgsConstructor; +import lombok.Getter; + /** * 业务操作类型 * - * @author ruoyi + * @author AprilWind */ +@Getter +@AllArgsConstructor public enum BusinessType { + /** - * 其它 + * 其它操作 */ - OTHER, + OTHER(0, "其它操作"), + + /** + * 查询 + */ + QUERY(1, "查询"), /** * 新增 */ - INSERT, + INSERT(2, "新增"), /** * 修改 */ - UPDATE, + UPDATE(3, "修改"), /** * 删除 */ - DELETE, - - /** - * 授权 - */ - GRANT, - - /** - * 导出 - */ - EXPORT, + DELETE(4, "删除"), /** * 导入 */ - IMPORT, + IMPORT(5, "导入"), /** - * 强退 + * 导出 */ - FORCE, + EXPORT(6, "导出"), /** - * 生成代码 + * 授权/赋权 */ - GENCODE, + GRANT(7, "授权"), /** * 清空数据 */ - CLEAN, + CLEAN(8, "清空数据"), + + /** + * 强制退出(用户登出) + */ + FORCE_LOGOUT(9, "强制退出"), + + /** + * 状态修改(启用/禁用/冻结/解冻) + */ + CHANGE_STATUS(10, "状态修改"), + + /** + * 重置密码 + */ + RESET_PASSWORD(11, "重置密码"), + + /** + * 批量删除 + */ + BATCH_DELETE(12, "批量删除"), + + /** + * 批量导入 + */ + BATCH_IMPORT(13, "批量导入"), + + /** + * 批量导出 + */ + BATCH_EXPORT(14, "批量导出"), + + /** + * 批量操作(通用) + */ + BATCH_OPERATE(15, "批量操作"), + + /** + * 审核操作(通过/驳回) + */ + AUDIT(16, "审核"), + + /** + * 发布/上线 + */ + PUBLISH(17, "发布"), + + /** + * 撤回/下线 + */ + REVOKE(18, "撤回"), + + /** + * 同步数据 + */ + SYNC(19, "同步数据"), + + /** + * 生成数据(生成编码、生成报表等) + */ + GENERATE(20, "生成数据"), + + /** + * 上传文件 + */ + UPLOAD(21, "上传文件"), + + /** + * 下载文件 + */ + DOWNLOAD(22, "下载文件"), + + /** + * 定时任务执行 + */ + TASK_EXECUTE(23, "定时任务执行"), + + /** + * 接口调用(第三方/开放API) + */ + API_CALL(24, "接口调用"), + + /** + * 登录 + */ + LOGIN(25, "登录"), + + /** + * 登出 + */ + LOGOUT(26, "登出"), + + /** + * 注册 + */ + REGISTER(27, "注册"), + + /** + * 作废/取消 + */ + CANCEL(28, "作废/取消"), + + /** + * 归档 + */ + ARCHIVE(29, "归档"), + + /** + * 配置修改 + */ + CONFIG_UPDATE(30, "配置修改"), + + /** + * 打印单据/报表 + */ + PRINT(31, "打印"), + + /** + * 复制数据/克隆 + */ + COPY(32, "复制"), + + /** + * 生成代码 + */ + GENCODE(33, "生成代码"); + + /** + * 业务类型编码 + */ + private final Integer code; + + /** + * 业务类型描述 + */ + private final String desc; + } diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperateChannel.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperateChannel.java new file mode 100644 index 000000000..f0825ac6e --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperateChannel.java @@ -0,0 +1,54 @@ +package org.dromara.common.log.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 操作渠道 + * + * @author AprilWind + */ +@Getter +@AllArgsConstructor +public enum OperateChannel { + + /** + * 管理后台 + */ + WEB(0, "管理后台"), + + /** + * 移动端APP + */ + APP(1, "移动端APP"), + + /** + * 小程序 + */ + MINI_APP(2, "小程序"), + + /** + * 开放接口 + */ + OPEN_API(3, "开放接口"), + + /** + * 定时任务 + */ + TASK(4, "定时任务"), + + /** + * 第三方调用 + */ + THIRD(5, "第三方调用"); + + /** + * 操作渠道编码 + */ + private final Integer code; + + /** + * 操作渠道描述 + */ + private final String desc; +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java deleted file mode 100644 index de9328b0a..000000000 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/enums/OperatorType.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.dromara.common.log.enums; - -/** - * 操作人类别 - * - * @author ruoyi - */ -public enum OperatorType { - /** - * 其它 - */ - OTHER, - - /** - * 后台用户 - */ - MANAGE, - - /** - * 手机端用户 - */ - MOBILE -} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java index a2b8b1a55..7d55b0283 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/org/dromara/common/log/event/OperLogEvent.java @@ -11,7 +11,6 @@ import java.time.LocalDateTime; * * @author Lion Li */ - @Data public class OperLogEvent implements Serializable { @@ -19,24 +18,34 @@ public class OperLogEvent implements Serializable { private static final long serialVersionUID = 1L; /** - * 日志主键 + * 业务模块名称 */ - private Long operId; + private String module; /** - * 操作模块 + * 操作功能名称 */ - private String title; + private String name; /** - * 业务类型(0其它 1新增 2修改 3删除) + * 操作描述(备注) + */ + private String remark; + + /** + * 标签(用于检索/分类) + */ + private String tags; + + /** + * 业务类型 */ private Integer businessType; /** - * 业务类型数组 + * 操作渠道 */ - private Integer[] businessTypes; + private Integer channel; /** * 请求方法 @@ -49,20 +58,20 @@ public class OperLogEvent implements Serializable { private String requestMethod; /** - * 操作类别(0其它 1后台用户 2手机端用户) + * 用户名 */ - private Integer operatorType; - - /** - * 操作人员 - */ - private String operName; + private String username; /** * 部门名称 */ private String deptName; + /** + * 用户类型 + */ + private String userType; + /** * 请求url */ @@ -74,9 +83,19 @@ public class OperLogEvent implements Serializable { private String operIp; /** - * 操作地点 + * 设备类型 */ - private String operLocation; + private String deviceType; + + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; /** * 请求参数 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java index 1e183a242..2bc83ea61 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysUserOnlineController.java @@ -83,7 +83,7 @@ public class SysUserOnlineController extends BaseController { * @return 操作结果 */ @SaCheckPermission("monitor:online:forceLogout") - @Log(title = "在线用户", businessType = BusinessType.FORCE) + @Log(title = "在线用户", businessType = BusinessType.FORCE_LOGOUT) @RepeatSubmit() @DeleteMapping("/{tokenId}") public R forceLogout(@PathVariable String tokenId) { @@ -120,7 +120,7 @@ public class SysUserOnlineController extends BaseController { * @param tokenId token值 * @return 操作结果 */ - @Log(title = "在线设备", businessType = BusinessType.FORCE) + @Log(title = "在线设备", businessType = BusinessType.FORCE_LOGOUT) @RepeatSubmit() @DeleteMapping("/myself/{tokenId}") public R remove(@PathVariable("tokenId") String tokenId) { diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java index 938dfbdf0..24e85bcd0 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOperLog.java @@ -13,7 +13,6 @@ import java.time.LocalDateTime; * * @author Lion Li */ - @Data @TableName("sys_oper_log") public class SysOperLog implements Serializable { @@ -28,15 +27,35 @@ public class SysOperLog implements Serializable { private Long operId; /** - * 操作模块 + * 业务模块名称 */ - private String title; + private String module; /** - * 业务类型(0其它 1新增 2修改 3删除) + * 操作功能名称 + */ + private String name; + + /** + * 操作描述(备注) + */ + private String remark; + + /** + * 标签(用于检索/分类) + */ + private String tags; + + /** + * 业务类型 */ private Integer businessType; + /** + * 操作渠道 + */ + private Integer channel; + /** * 请求方法 */ @@ -53,15 +72,20 @@ public class SysOperLog implements Serializable { private Integer operatorType; /** - * 操作人员 + * 用户名 */ - private String operName; + private String username; /** * 部门名称 */ private String deptName; + /** + * 用户类型 + */ + private String userType; + /** * 请求url */ @@ -72,11 +96,26 @@ public class SysOperLog implements Serializable { */ private String operIp; + /** + * 设备类型 + */ + private String deviceType; + /** * 操作地点 */ private String operLocation; + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + /** * 请求参数 */ diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java index e51ac80e0..949eef282 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysOperLogBo.java @@ -35,22 +35,42 @@ public class SysOperLogBo implements Serializable { private Long operId; /** - * 模块标题 + * 业务模块名称 */ - private String title; + private String module; /** - * 业务类型(0其它 1新增 2修改 3删除) + * 操作功能名称 + */ + private String name; + + /** + * 操作描述(备注) + */ + private String remark; + + /** + * 标签(用于检索/分类) + */ + private String tags; + + /** + * 业务类型 */ private Integer businessType; + /** + * 操作渠道 + */ + private Integer channel; + /** * 业务类型数组 */ private Integer[] businessTypes; /** - * 方法名称 + * 请求方法 */ private String method; @@ -65,9 +85,9 @@ public class SysOperLogBo implements Serializable { private Integer operatorType; /** - * 操作人员 + * 用户名 */ - private String operName; + private String username; /** * 部门名称 @@ -75,20 +95,40 @@ public class SysOperLogBo implements Serializable { private String deptName; /** - * 请求URL + * 用户类型 + */ + private String userType; + + /** + * 请求url */ private String operUrl; /** - * 主机地址 + * 操作地址 */ private String operIp; + /** + * 设备类型 + */ + private String deviceType; + /** * 操作地点 */ private String operLocation; + /** + * 浏览器类型 + */ + private String browser; + + /** + * 操作系统 + */ + private String os; + /** * 请求参数 */ diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java index 175fb0951..1eb5ce49e 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOperLogServiceImpl.java @@ -1,5 +1,6 @@ package org.dromara.system.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ArrayUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -43,10 +44,11 @@ public class SysOperLogServiceImpl implements ISysOperLogService { @Async @EventListener public void recordOper(OperLogEvent operLogEvent) { - SysOperLogBo operLog = MapstructUtils.convert(operLogEvent, SysOperLogBo.class); + SysOperLog operLog = BeanUtil.copyProperties(operLogEvent, SysOperLog.class); // 远程查询操作地点 operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); - insertOperlog(operLog); + operLog.setOperTime(LocalDateTime.now()); + baseMapper.insert(operLog); } /** @@ -76,7 +78,7 @@ public class SysOperLogServiceImpl implements ISysOperLogService { Map params = operLog.getParams(); return new LambdaQueryWrapper() .like(StringUtils.isNotBlank(operLog.getOperIp()), SysOperLog::getOperIp, operLog.getOperIp()) - .like(StringUtils.isNotBlank(operLog.getTitle()), SysOperLog::getTitle, operLog.getTitle()) + .like(StringUtils.isNotBlank(operLog.getModule()), SysOperLog::getModule, operLog.getModule()) .eq(operLog.getBusinessType() != null && operLog.getBusinessType() > 0, SysOperLog::getBusinessType, operLog.getBusinessType()) .func(f -> { @@ -86,7 +88,7 @@ public class SysOperLogServiceImpl implements ISysOperLogService { }) .eq(operLog.getStatus() != null, SysOperLog::getStatus, operLog.getStatus()) - .like(StringUtils.isNotBlank(operLog.getOperName()), SysOperLog::getOperName, operLog.getOperName()) + .like(StringUtils.isNotBlank(operLog.getUsername()), SysOperLog::getUsername, operLog.getUsername()) .between(params.get("beginTime") != null && params.get("endTime") != null, SysOperLog::getOperTime, params.get("beginTime"), params.get("endTime")); } diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql index 5ea96619a..f4ed55ce9 100644 --- a/script/sql/ry_vue_5.X.sql +++ b/script/sql/ry_vue_5.X.sql @@ -506,16 +506,24 @@ insert into sys_user_post values ('1', '1'); -- ---------------------------- create table sys_oper_log ( oper_id bigint(20) not null comment '日志主键', - title varchar(50) default '' comment '模块标题', - business_type int(2) default 0 comment '业务类型(0其它 1新增 2修改 3删除)', - method varchar(100) default '' comment '方法名称', + module varchar(50) default '' comment '业务模块名称', + name varchar(50) default '' comment '操作功能名称', + remark varchar(255) default '' comment '操作描述(备注)', + tags varchar(255) default '' comment '标签(用于检索/分类)', + business_type int(2) default 0 comment '业务类型', + channel int(1) default 0 comment '操作渠道', + method varchar(100) default '' comment '请求方法', request_method varchar(10) default '' comment '请求方式', - operator_type int(1) default 0 comment '操作类别(0其它 1后台用户 2手机端用户)', - oper_name varchar(50) default '' comment '操作人员', + operator_type int(1) default 0 comment '操作类别', + username varchar(50) default '' comment '用户名', dept_name varchar(50) default '' comment '部门名称', - oper_url varchar(255) default '' comment '请求URL', - oper_ip varchar(128) default '' comment '主机地址', + user_type varchar(20) default '' comment '用户类型', + oper_url varchar(255) default '' comment '请求url', + oper_ip varchar(128) default '' comment '操作地址', + device_type varchar(50) default '' comment '设备类型', oper_location varchar(255) default '' comment '操作地点', + browser varchar(50) default '' comment '浏览器类型', + os varchar(50) default '' comment '操作系统', oper_param varchar(4000) default '' comment '请求参数', json_result varchar(4000) default '' comment '返回参数', status int(1) default 0 comment '操作状态(0正常 1异常)',