From 9233d09edce831eba97583f8ce2b91f6cace0f2c Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Wed, 1 Jul 2026 15:43:26 +0800 Subject: [PATCH] =?UTF-8?q?feat(monitor):=20=E6=B7=BB=E5=8A=A0=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=97=A5=E5=BF=97=E7=BB=A9=E6=95=88=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在SysOperLogService中新增绩效概览、人员绩效和模块排行接口 - 在SysOperLogMapper中添加模块统计、人员统计和全局概览查询方法 - 在SysOperLogMapper.xml中实现绩效相关的SQL查询和ResultMap - 在SysOperLogServiceImpl中实现绩效统计业务逻辑和评分算法 - 创建OperModuleStatVO、OperPersonVO和OperSummaryVO数据传输对象 - 新增OperPerformanceController提供绩效统计API接口 - 添加前端performance页面实现数据可视化展示和图表渲染 --- .../monitor/OperPerformanceController.java | 58 +++ .../domain/bo/OperPerformanceQuery.java | 43 ++ .../system/domain/vo/OperModuleStatVO.java | 63 +++ .../klp/system/domain/vo/OperPersonVO.java | 101 ++++ .../klp/system/domain/vo/OperSummaryVO.java | 48 ++ .../klp/system/mapper/SysOperLogMapper.java | 25 + .../system/service/ISysOperLogService.java | 19 + .../service/impl/SysOperLogServiceImpl.java | 70 ++- .../mapper/system/SysOperLogMapper.xml | 169 ++++++ klp-ui/src/api/monitor/performance.js | 28 + .../src/views/monitor/performance/index.vue | 481 ++++++++++++++++++ 11 files changed, 1101 insertions(+), 4 deletions(-) create mode 100644 klp-admin/src/main/java/com/klp/web/controller/monitor/OperPerformanceController.java create mode 100644 klp-system/src/main/java/com/klp/system/domain/bo/OperPerformanceQuery.java create mode 100644 klp-system/src/main/java/com/klp/system/domain/vo/OperModuleStatVO.java create mode 100644 klp-system/src/main/java/com/klp/system/domain/vo/OperPersonVO.java create mode 100644 klp-system/src/main/java/com/klp/system/domain/vo/OperSummaryVO.java create mode 100644 klp-ui/src/api/monitor/performance.js create mode 100644 klp-ui/src/views/monitor/performance/index.vue diff --git a/klp-admin/src/main/java/com/klp/web/controller/monitor/OperPerformanceController.java b/klp-admin/src/main/java/com/klp/web/controller/monitor/OperPerformanceController.java new file mode 100644 index 000000000..7416f808d --- /dev/null +++ b/klp-admin/src/main/java/com/klp/web/controller/monitor/OperPerformanceController.java @@ -0,0 +1,58 @@ +package com.klp.web.controller.monitor; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.R; +import com.klp.system.domain.bo.OperPerformanceQuery; +import com.klp.system.domain.vo.OperModuleStatVO; +import com.klp.system.domain.vo.OperPersonVO; +import com.klp.system.domain.vo.OperSummaryVO; +import com.klp.system.service.ISysOperLogService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +/** + * 绩效汇总 + * + * @author Reasonix + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/monitor/performance") +public class OperPerformanceController extends BaseController { + + private final ISysOperLogService operLogService; + + /** + * 绩效概览统计 + */ + @SaCheckPermission("monitor:performance:list") + @GetMapping("/summary") + public R summary(OperPerformanceQuery query) { + return R.ok(operLogService.selectPerformanceSummary(query)); + } + + /** + * 人员绩效列表(含模块明细) + */ + @SaCheckPermission("monitor:performance:list") + @GetMapping("/person") + public R> person(OperPerformanceQuery query) { + return R.ok(operLogService.selectPersonPerformance(query)); + } + + /** + * 模块使用排行 + */ + @SaCheckPermission("monitor:performance:list") + @GetMapping("/module") + public R> module(OperPerformanceQuery query) { + return R.ok(operLogService.selectModuleRanking(query)); + } +} diff --git a/klp-system/src/main/java/com/klp/system/domain/bo/OperPerformanceQuery.java b/klp-system/src/main/java/com/klp/system/domain/bo/OperPerformanceQuery.java new file mode 100644 index 000000000..e75f0e93b --- /dev/null +++ b/klp-system/src/main/java/com/klp/system/domain/bo/OperPerformanceQuery.java @@ -0,0 +1,43 @@ +package com.klp.system.domain.bo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 操作日志绩效查询参数 + * + * @author Reasonix + */ +@Data +@NoArgsConstructor +public class OperPerformanceQuery implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 开始时间 + */ + private String beginTime; + + /** + * 结束时间 + */ + private String endTime; + + /** + * 部门名称 + */ + private String deptName; + + /** + * 操作人员 + */ + private String operName; + + /** + * 模块标题 + */ + private String title; +} diff --git a/klp-system/src/main/java/com/klp/system/domain/vo/OperModuleStatVO.java b/klp-system/src/main/java/com/klp/system/domain/vo/OperModuleStatVO.java new file mode 100644 index 000000000..e9c26ee3e --- /dev/null +++ b/klp-system/src/main/java/com/klp/system/domain/vo/OperModuleStatVO.java @@ -0,0 +1,63 @@ +package com.klp.system.domain.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 模块维度统计 VO + * + * @author Reasonix + */ +@Data +@NoArgsConstructor +public class OperModuleStatVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 模块标题 + */ + private String title; + + /** + * 该模块操作总次数 + */ + private Long totalCount; + + /** + * 新增次数 (businessType=1) + */ + private Long addCount; + + /** + * 修改次数 (businessType=2) + */ + private Long editCount; + + /** + * 删除次数 (businessType=3) + */ + private Long deleteCount; + + /** + * 其它次数 (businessType=0) + */ + private Long otherCount; + + /** + * 成功率 (成功次数/总次数 * 100) + */ + private Double successRate; + + /** + * 操作人员(用于人员-模块明细关联) + */ + private String operName; + + /** + * 使用该模块的人数 + */ + private Long personCount; +} diff --git a/klp-system/src/main/java/com/klp/system/domain/vo/OperPersonVO.java b/klp-system/src/main/java/com/klp/system/domain/vo/OperPersonVO.java new file mode 100644 index 000000000..39d3f5ff1 --- /dev/null +++ b/klp-system/src/main/java/com/klp/system/domain/vo/OperPersonVO.java @@ -0,0 +1,101 @@ +package com.klp.system.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 人员绩效汇总 VO(含模块明细) + * + * @author Reasonix + */ +@Data +@NoArgsConstructor +@ExcelIgnoreUnannotated +public class OperPersonVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 操作人员 + */ + @ExcelProperty(value = "操作人员") + private String operName; + + /** + * 部门名称 + */ + @ExcelProperty(value = "部门名称") + private String deptName; + + /** + * 总操作次数 + */ + @ExcelProperty(value = "总操作次数") + private Long totalCount; + + /** + * 成功次数 + */ + @ExcelProperty(value = "成功次数") + private Long successCount; + + /** + * 失败次数 + */ + @ExcelProperty(value = "失败次数") + private Long failCount; + + /** + * 成功率 (%) + */ + @ExcelProperty(value = "成功率(%)") + private Double successRate; + + /** + * 新增次数 + */ + @ExcelProperty(value = "新增次数") + private Long addCount; + + /** + * 修改次数 + */ + @ExcelProperty(value = "修改次数") + private Long editCount; + + /** + * 删除次数 + */ + @ExcelProperty(value = "删除次数") + private Long deleteCount; + + /** + * 其它次数 + */ + @ExcelProperty(value = "其它次数") + private Long otherCount; + + /** + * 综合评分 + */ + @ExcelProperty(value = "综合评分") + private Double score; + + /** + * 最近操作时间 + */ + @ExcelProperty(value = "最近操作时间") + private Date lastOperTime; + + /** + * 该人员的模块明细列表 + */ + private List moduleStats = new ArrayList<>(); +} diff --git a/klp-system/src/main/java/com/klp/system/domain/vo/OperSummaryVO.java b/klp-system/src/main/java/com/klp/system/domain/vo/OperSummaryVO.java new file mode 100644 index 000000000..17601e3d0 --- /dev/null +++ b/klp-system/src/main/java/com/klp/system/domain/vo/OperSummaryVO.java @@ -0,0 +1,48 @@ +package com.klp.system.domain.vo; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 绩效概览卡片 VO + * + * @author Reasonix + */ +@Data +@NoArgsConstructor +public class OperSummaryVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 总操作量 + */ + private Long totalOperations; + + /** + * 成功操作数 + */ + private Long successCount; + + /** + * 失败操作数 + */ + private Long failCount; + + /** + * 活跃人数 + */ + private Long activePersonCount; + + /** + * 活跃模块数 + */ + private Long activeModuleCount; + + /** + * 人均操作数 + */ + private Double avgPerPerson; +} diff --git a/klp-system/src/main/java/com/klp/system/mapper/SysOperLogMapper.java b/klp-system/src/main/java/com/klp/system/mapper/SysOperLogMapper.java index 15ba42e4d..2dfc22d48 100644 --- a/klp-system/src/main/java/com/klp/system/mapper/SysOperLogMapper.java +++ b/klp-system/src/main/java/com/klp/system/mapper/SysOperLogMapper.java @@ -2,6 +2,12 @@ package com.klp.system.mapper; import com.klp.common.core.mapper.BaseMapperPlus; import com.klp.system.domain.SysOperLog; +import com.klp.system.domain.bo.OperPerformanceQuery; +import com.klp.system.domain.vo.OperModuleStatVO; +import com.klp.system.domain.vo.OperPersonVO; +import com.klp.system.domain.vo.OperSummaryVO; + +import java.util.List; /** * 操作日志 数据层 @@ -10,4 +16,23 @@ import com.klp.system.domain.SysOperLog; */ public interface SysOperLogMapper extends BaseMapperPlus { + /** + * 模块全局统计 + */ + List selectModuleSummary(OperPerformanceQuery query); + + /** + * 按人员统计 + */ + List selectPersonSummary(OperPerformanceQuery query); + + /** + * 按人员-模块明细统计 + */ + List selectPersonModuleDetail(OperPerformanceQuery query); + + /** + * 全局概览统计 + */ + OperSummaryVO selectGlobalSummary(OperPerformanceQuery query); } diff --git a/klp-system/src/main/java/com/klp/system/service/ISysOperLogService.java b/klp-system/src/main/java/com/klp/system/service/ISysOperLogService.java index 310016202..9f11aeeeb 100644 --- a/klp-system/src/main/java/com/klp/system/service/ISysOperLogService.java +++ b/klp-system/src/main/java/com/klp/system/service/ISysOperLogService.java @@ -3,6 +3,10 @@ package com.klp.system.service; import com.klp.common.core.domain.PageQuery; import com.klp.common.core.page.TableDataInfo; import com.klp.system.domain.SysOperLog; +import com.klp.system.domain.bo.OperPerformanceQuery; +import com.klp.system.domain.vo.OperModuleStatVO; +import com.klp.system.domain.vo.OperPersonVO; +import com.klp.system.domain.vo.OperSummaryVO; import java.util.List; @@ -50,4 +54,19 @@ public interface ISysOperLogService { * 清空操作日志 */ void cleanOperLog(); + + /** + * 绩效概览统计 + */ + OperSummaryVO selectPerformanceSummary(OperPerformanceQuery query); + + /** + * 人员绩效列表(含模块明细) + */ + List selectPersonPerformance(OperPerformanceQuery query); + + /** + * 模块使用排行 + */ + List selectModuleRanking(OperPerformanceQuery query); } diff --git a/klp-system/src/main/java/com/klp/system/service/impl/SysOperLogServiceImpl.java b/klp-system/src/main/java/com/klp/system/service/impl/SysOperLogServiceImpl.java index 89e3df669..00aa7e7fb 100644 --- a/klp-system/src/main/java/com/klp/system/service/impl/SysOperLogServiceImpl.java +++ b/klp-system/src/main/java/com/klp/system/service/impl/SysOperLogServiceImpl.java @@ -10,6 +10,10 @@ import com.klp.common.core.page.TableDataInfo; import com.klp.common.utils.StringUtils; import com.klp.common.utils.ip.AddressUtils; import com.klp.system.domain.SysOperLog; +import com.klp.system.domain.bo.OperPerformanceQuery; +import com.klp.system.domain.vo.OperModuleStatVO; +import com.klp.system.domain.vo.OperPersonVO; +import com.klp.system.domain.vo.OperSummaryVO; import com.klp.system.mapper.SysOperLogMapper; import com.klp.system.service.ISysOperLogService; import lombok.RequiredArgsConstructor; @@ -17,10 +21,8 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * 操作日志 服务层处理 @@ -138,4 +140,64 @@ public class SysOperLogServiceImpl implements ISysOperLogService { public void cleanOperLog() { baseMapper.delete(new LambdaQueryWrapper<>()); } + + @Override + public OperSummaryVO selectPerformanceSummary(OperPerformanceQuery query) { + return baseMapper.selectGlobalSummary(query); + } + + @Override + public List selectModuleRanking(OperPerformanceQuery query) { + return baseMapper.selectModuleSummary(query); + } + + @Override + public List selectPersonPerformance(OperPerformanceQuery query) { + // 1. 查询人员汇总 + List personList = baseMapper.selectPersonSummary(query); + if (personList == null || personList.isEmpty()) { + return Collections.emptyList(); + } + + // 2. 查询人员-模块明细 + List allModuleDetails = baseMapper.selectPersonModuleDetail(query); + + // 3. 按人员分组模块明细 + Map> moduleMap = Collections.emptyMap(); + if (allModuleDetails != null && !allModuleDetails.isEmpty()) { + moduleMap = allModuleDetails.stream() + .collect(Collectors.groupingBy(m -> m.getOperName() != null ? m.getOperName() : "")); + } + + // 4. 计算全局最大值用于评分归一化 + long maxTotalCount = personList.stream() + .mapToLong(p -> p.getTotalCount() != null ? p.getTotalCount() : 0) + .max().orElse(1); + long maxModuleCount = moduleMap.values().stream() + .mapToInt(List::size) + .max().orElse(1); + + // 5. 组装数据并计算综合评分 + for (OperPersonVO person : personList) { + String name = person.getOperName(); + List details = moduleMap.getOrDefault(name, Collections.emptyList()); + person.setModuleStats(details); + + // 计算综合评分: 次数×40% + 成功率×30% + 模块覆盖度×30% + double countScore = (person.getTotalCount() != null ? person.getTotalCount() : 0) * 1.0 / maxTotalCount * 40; + double successScore = (person.getSuccessRate() != null ? person.getSuccessRate() : 0) / 100.0 * 30; + double moduleScore = (maxModuleCount > 0 ? details.size() * 1.0 / maxModuleCount : 0) * 30; + double score = Math.round((countScore + successScore + moduleScore) * 100.0) / 100.0; + person.setScore(score); + } + + // 6. 按评分降序排序 + personList.sort((a, b) -> { + double sa = a.getScore() != null ? a.getScore() : 0; + double sb = b.getScore() != null ? b.getScore() : 0; + return Double.compare(sb, sa); + }); + + return personList; + } } diff --git a/klp-system/src/main/resources/mapper/system/SysOperLogMapper.xml b/klp-system/src/main/resources/mapper/system/SysOperLogMapper.xml index 21d120780..81f07e5e7 100644 --- a/klp-system/src/main/resources/mapper/system/SysOperLogMapper.xml +++ b/klp-system/src/main/resources/mapper/system/SysOperLogMapper.xml @@ -23,4 +23,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/klp-ui/src/api/monitor/performance.js b/klp-ui/src/api/monitor/performance.js new file mode 100644 index 000000000..a79abc42e --- /dev/null +++ b/klp-ui/src/api/monitor/performance.js @@ -0,0 +1,28 @@ +import request from '@/utils/request' + +// 绩效概览统计 +export function getSummary(params) { + return request({ + url: '/monitor/performance/summary', + method: 'get', + params: params + }) +} + +// 人员绩效列表(含模块明细) +export function getPersonList(params) { + return request({ + url: '/monitor/performance/person', + method: 'get', + params: params + }) +} + +// 模块使用排行 +export function getModuleRanking(params) { + return request({ + url: '/monitor/performance/module', + method: 'get', + params: params + }) +} diff --git a/klp-ui/src/views/monitor/performance/index.vue b/klp-ui/src/views/monitor/performance/index.vue new file mode 100644 index 000000000..92de84554 --- /dev/null +++ b/klp-ui/src/views/monitor/performance/index.vue @@ -0,0 +1,481 @@ + + + + +