refactor: 重构日志管理相关接口

This commit is contained in:
2024-03-25 23:25:37 +08:00
parent 8a41b96687
commit 7793f82009
30 changed files with 421 additions and 702 deletions

View File

@@ -13,12 +13,6 @@
<description>系统监控模块(存放系统监控相关业务功能,例如:在线用户、日志管理等)</description>
<dependencies>
<!-- ContiNew Starter 日志模块 - HttpTraceProSpring Boot Actuator HttpTrace 定制增强版) -->
<dependency>
<groupId>top.charles7c.continew</groupId>
<artifactId>continew-starter-log-httptrace-pro</artifactId>
</dependency>
<!-- 系统管理模块(存放系统管理模块相关功能,例如:部门管理、角色管理、用户管理等) -->
<dependency>
<groupId>top.charles7c.continew</groupId>

View File

@@ -1,45 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import top.charles7c.continew.admin.monitor.mapper.LogMapper;
import top.charles7c.continew.admin.system.service.UserService;
import top.charles7c.continew.starter.log.core.dao.LogDao;
import top.charles7c.continew.starter.log.httptracepro.autoconfigure.ConditionalOnEnabledLog;
import top.charles7c.continew.starter.web.autoconfigure.trace.TraceProperties;
/**
* 日志配置
*
* @author Charles7c
* @since 2022/12/24 23:15
*/
@Configuration
@ConditionalOnEnabledLog
public class LogConfiguration {
/**
* 日志持久层接口本地实现类
*/
@Bean
public LogDao logDao(UserService userService, LogMapper logMapper, TraceProperties traceProperties) {
return new LogDaoLocalImpl(userService, logMapper, traceProperties);
}
}

View File

@@ -1,124 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.config;
import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import top.charles7c.continew.admin.auth.model.req.AccountLoginReq;
import top.charles7c.continew.admin.common.constant.SysConstants;
import top.charles7c.continew.admin.monitor.enums.LogStatusEnum;
import top.charles7c.continew.admin.monitor.mapper.LogMapper;
import top.charles7c.continew.admin.monitor.model.entity.LogDO;
import top.charles7c.continew.admin.system.service.UserService;
import top.charles7c.continew.starter.core.constant.StringConstants;
import top.charles7c.continew.starter.core.util.ExceptionUtils;
import top.charles7c.continew.starter.log.core.dao.LogDao;
import top.charles7c.continew.starter.log.core.model.LogRecord;
import top.charles7c.continew.starter.log.core.model.LogRequest;
import top.charles7c.continew.starter.log.core.model.LogResponse;
import top.charles7c.continew.starter.web.autoconfigure.trace.TraceProperties;
import top.charles7c.continew.starter.web.model.R;
import java.net.URI;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
/**
* 日志持久层接口本地实现类
*
* @author Charles7c
* @since 2023/12/16 23:55
*/
@RequiredArgsConstructor
public class LogDaoLocalImpl implements LogDao {
private final UserService userService;
private final LogMapper logMapper;
private final TraceProperties traceProperties;
@Async
@Override
public void add(LogRecord logRecord) {
LogDO logDO = new LogDO();
logDO.setDescription(logRecord.getDescription());
String module = logRecord.getModule();
logDO.setModule(StrUtil.isNotBlank(module)
? logRecord.getModule().replace("API", StringConstants.EMPTY).trim()
: null);
logDO.setCreateTime(LocalDateTime.ofInstant(logRecord.getTimestamp(), ZoneId.systemDefault()));
logDO.setTimeTaken(logRecord.getTimeTaken().toMillis());
// 请求信息
LogRequest logRequest = logRecord.getRequest();
logDO.setRequestMethod(logRequest.getMethod());
URI requestUrl = logRequest.getUrl();
String requestUri = requestUrl.getPath();
logDO.setRequestUrl(requestUrl.toString());
Map<String, String> requestHeaderMap = logRequest.getHeaders();
logDO.setRequestHeaders(JSONUtil.toJsonStr(requestHeaderMap));
String requestBody = logRequest.getBody();
logDO.setRequestBody(requestBody);
logDO.setIp(logRequest.getIp());
logDO.setAddress(logRequest.getAddress());
logDO.setBrowser(logRequest.getBrowser());
logDO.setOs(StrUtil.subBefore(logRequest.getOs(), " or", false));
// 响应信息
LogResponse logResponse = logRecord.getResponse();
Integer statusCode = logResponse.getStatus();
logDO.setStatusCode(statusCode);
Map<String, String> responseHeaders = logResponse.getHeaders();
logDO.setResponseHeaders(JSONUtil.toJsonStr(responseHeaders));
logDO.setTraceId(responseHeaders.get(traceProperties.getHeaderName()));
String responseBody = logResponse.getBody();
logDO.setResponseBody(responseBody);
// 状态
logDO.setStatus(statusCode >= HttpStatus.HTTP_BAD_REQUEST ? LogStatusEnum.FAILURE : LogStatusEnum.SUCCESS);
if (StrUtil.isNotBlank(responseBody) && JSONUtil.isTypeJSON(responseBody)) {
R result = JSONUtil.toBean(responseBody, R.class);
if (!result.isSuccess()) {
logDO.setStatus(LogStatusEnum.FAILURE);
logDO.setErrorMsg(result.getMsg());
}
// 操作人
if (requestUri.startsWith(SysConstants.LOGOUT_URI)) {
Long loginId = Convert.toLong(result.getData(), -1L);
logDO.setCreateUser(-1 != loginId ? loginId : null);
} else if (result.isSuccess() && requestUri.startsWith(SysConstants.LOGIN_URI)) {
AccountLoginReq loginReq = JSONUtil.toBean(requestBody, AccountLoginReq.class);
logDO.setCreateUser(ExceptionUtils.exToNull(() -> userService.getByUsername(loginReq.getUsername())
.getId()));
}
}
// 操作人
if (!requestUri.startsWith(SysConstants.LOGOUT_URI) && MapUtil.isNotEmpty(requestHeaderMap) && requestHeaderMap
.containsKey(HttpHeaders.AUTHORIZATION)) {
String authorization = requestHeaderMap.get(HttpHeaders.AUTHORIZATION);
String token = authorization.replace(SaManager.getConfig()
.getTokenPrefix() + StringConstants.SPACE, StringConstants.EMPTY);
logDO.setCreateUser(Convert.toLong(StpUtil.getLoginIdByToken(token)));
}
logMapper.insert(logDO);
}
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import top.charles7c.continew.starter.data.mybatis.plus.base.IBaseEnum;
/**
* 操作状态枚举
*
* @author Charles7c
* @since 2022/12/25 9:09
*/
@Getter
@RequiredArgsConstructor
public enum LogStatusEnum implements IBaseEnum<Integer> {
/** 成功 */
SUCCESS(1, "成功"),
/** 失败 */
FAILURE(2, "失败"),;
private final Integer value;
private final String description;
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import top.charles7c.continew.admin.monitor.model.entity.LogDO;
import top.charles7c.continew.admin.monitor.model.resp.DashboardAccessTrendResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardPopularModuleResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardTotalResp;
import top.charles7c.continew.starter.data.mybatis.plus.base.BaseMapper;
/**
* 系统日志 Mapper
*
* @author Charles7c
* @since 2022/12/22 21:47
*/
public interface LogMapper extends BaseMapper<LogDO> {
/**
* 查询仪表盘总计信息
*
* @return 仪表盘总计信息
*/
DashboardTotalResp selectDashboardTotal();
/**
* 查询仪表盘访问趋势信息
*
* @param days 日期数
*
* @return 仪表盘访问趋势信息
*/
List<DashboardAccessTrendResp> selectListDashboardAccessTrend(@Param("days") Integer days);
/**
* 查询仪表盘热门模块列表
*
* @return 仪表盘热门模块列表
*/
List<DashboardPopularModuleResp> selectListDashboardPopularModule();
/**
* 查询仪表盘访客地域分布信息
*
* @return 仪表盘访客地域分布信息
*/
List<Map<String, Object>> selectListDashboardGeoDistribution();
}

View File

@@ -1,141 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import top.charles7c.continew.admin.monitor.enums.LogStatusEnum;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 系统日志实体
*
* @author Charles7c
* @since 2022/12/25 9:11
*/
@Data
@TableName("sys_log")
public class LogDO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId
private Long id;
/**
* 链路 ID
*/
private String traceId;
/**
* 日志描述
*/
private String description;
/**
* 所属模块
*/
private String module;
/**
* 请求 URL
*/
private String requestUrl;
/**
* 请求方式
*/
private String requestMethod;
/**
* 请求头
*/
private String requestHeaders;
/**
* 请求体
*/
private String requestBody;
/**
* 状态码
*/
private Integer statusCode;
/**
* 响应头
*/
private String responseHeaders;
/**
* 响应体
*/
private String responseBody;
/**
* 耗时ms
*/
private Long timeTaken;
/**
* IP
*/
private String ip;
/**
* IP 归属地
*/
private String address;
/**
* 浏览器
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 状态
*/
private LogStatusEnum status;
/**
* 错误信息
*/
private String errorMsg;
/**
* 创建人
*/
private Long createUser;
/**
* 创建时间
*/
private LocalDateTime createTime;
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.query;
import cn.hutool.core.date.DatePattern;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import top.charles7c.continew.starter.data.core.annotation.Query;
import top.charles7c.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 登录日志查询条件
*
* @author Charles7c
* @since 2023/1/16 23:25
*/
@Data
@Schema(description = "登录日志查询条件")
public class LoginLogQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 登录状态
*/
@Schema(description = "登录状态1成功2失败", example = "1")
private Integer status;
/**
* 登录时间
*/
@Schema(description = "登录时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
@Query(type = QueryType.BETWEEN)
@DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
private List<Date> createTime;
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.query;
import cn.hutool.core.date.DatePattern;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import top.charles7c.continew.starter.data.core.annotation.Query;
import top.charles7c.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 操作日志查询条件
*
* @author Charles7c
* @since 2023/1/15 11:43
*/
@Data
@Schema(description = "操作日志查询条件")
public class OperationLogQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 操作内容
*/
@Schema(description = "操作内容", example = "新增数据")
@Query(type = QueryType.LIKE)
private String description;
/**
* 操作状态
*/
@Schema(description = "操作状态1成功2失败", example = "1")
private Integer status;
/**
* 操作时间
*/
@Schema(description = "操作时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
@Query(type = QueryType.BETWEEN)
@DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
private List<Date> createTime;
/**
* 操作人
*/
@Schema(description = "操作人", example = "张三")
@Query(columns = "create_user")
private Long uid;
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.query;
import cn.hutool.core.date.DatePattern;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import top.charles7c.continew.starter.data.core.annotation.Query;
import top.charles7c.continew.starter.data.core.enums.QueryType;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 系统日志查询条件
*
* @author Charles7c
* @since 2023/1/17 23:31
*/
@Data
@Schema(description = "系统日志查询条件")
public class SystemLogQuery implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 链路 ID
*/
@Schema(description = "链路 ID", example = "904846526308876288")
private String traceId;
/**
* 创建时间
*/
@Schema(description = "创建时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
@Query(type = QueryType.BETWEEN)
@DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
private List<Date> createTime;
}

View File

@@ -1,56 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import java.io.Serializable;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 仪表盘-访问趋势信息
*
* @author Charles7c
* @since 2023/9/9 20:20
*/
@Data
@Schema(description = "仪表盘-访问趋势信息")
public class DashboardAccessTrendResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 日期
*/
@Schema(description = "日期", example = "2023-08-08")
private String date;
/**
* 浏览量PV
*/
@Schema(description = "浏览量PV", example = "1000")
private Long pvCount;
/**
* IP 数
*/
@Schema(description = "IP 数", example = "500")
private Long ipCount;
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 仪表盘-访客地域分布信息
*
* @author Charles7c
* @since 2023/9/9 12:07
*/
@Data
@Schema(description = "仪表盘-访客地域分布信息")
public class DashboardGeoDistributionResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 地点列表
*/
@Schema(description = "地点列表", example = "[\"中国北京北京市\",\"中国广东省深圳市\"]")
private List<String> locations;
/**
* 地点 IP 统计信息
*/
@Schema(description = "地点 IP 统计信息", example = "[{\"name\":\"中国北京北京市\",\"value\":1000},{\"name\":\"中国广东省深圳市\",\"value\": 500}]")
private List<Map<String, Object>> locationIpStatistics;
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 仪表盘-热门模块信息
*
* @author Charles7c
* @since 2023/9/9 9:52
*/
@Data
@Schema(description = "仪表盘-热门模块信息")
public class DashboardPopularModuleResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 模块
*/
@Schema(description = "模块", example = "角色管理")
private String module;
/**
* 浏览量PV
*/
@Schema(description = "浏览量PV", example = "1234")
private Long pvCount;
/**
* 较昨日新增 PV百分比
*/
@Schema(description = "较昨日新增(百分比)", example = "23.4")
private BigDecimal newPvFromYesterday;
/**
* 今日浏览量PV
*/
@JsonIgnore
private Long todayPvCount;
/**
* 昨日浏览量PV
*/
@JsonIgnore
private Long yesterdayPvCount;
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* 仪表盘-总计信息
*
* @author Charles7c
* @since 2023/9/8 21:32
*/
@Data
@Schema(description = "仪表盘-总计信息")
public class DashboardTotalResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 浏览量PV
*/
@Schema(description = "浏览量PV", example = "88888")
private Long pvCount;
/**
* IP 数
*/
@Schema(description = "IP 数", example = "66666")
private Long ipCount;
/**
* 今日浏览量PV
*/
@Schema(description = "今日浏览量PV", example = "1234")
private Long todayPvCount;
/**
* 较昨日新增 PV百分比
*/
@Schema(description = "较昨日新增(百分比)", example = "23.4")
private BigDecimal newPvFromYesterday;
/**
* 昨日浏览量PV
*/
@JsonIgnore
private Long yesterdayPvCount;
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import cn.crane4j.annotation.Assemble;
import cn.crane4j.annotation.Mapping;
import cn.crane4j.annotation.condition.ConditionOnPropertyNotNull;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import top.charles7c.continew.admin.common.constant.ContainerConstants;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 基础日志信息
*
* @author Charles7c
* @since 2023/1/17 21:43
*/
@Data
public class LogResp implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* ID
*/
@Schema(description = "ID", example = "1")
private Long id;
/**
* 创建人
*/
@JsonIgnore
@ConditionOnPropertyNotNull
@Assemble(container = ContainerConstants.USER_NICKNAME, props = @Mapping(ref = "createUserString"))
private Long createUser;
/**
* 创建人
*/
@Schema(description = "创建人", example = "张三")
private String createUserString;
/**
* 创建时间
*/
@Schema(description = "创建时间", example = "2023-08-08 08:08:08", type = "string")
private LocalDateTime createTime;
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.continew.admin.monitor.enums.LogStatusEnum;
/**
* 登录日志信息
*
* @author Charles7c
* @since 2023/1/16 23:19
*/
@Data
@Schema(description = "登录日志信息")
public class LoginLogResp extends LogResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 登录行为
*/
@Schema(description = "登录行为", example = "用户登录")
private String description;
/**
* 登录状态
*/
@Schema(description = "登录状态1成功2失败", type = "Integer", allowableValues = {"1", "2"}, example = "1")
private LogStatusEnum status;
/**
* 登录 IP
*/
@Schema(description = "登录 IP", example = "192.168.0.1")
private String ip;
/**
* 登录地点
*/
@Schema(description = "登录地点", example = "中国北京北京市")
private String address;
/**
* 浏览器
*/
@Schema(description = "浏览器", example = "Chrome 115.0.0.0")
private String browser;
/**
* 操作系统
*/
@Schema(description = "操作系统", example = "Windows 10")
private String os;
/**
* 错误信息
*/
@Schema(description = "错误信息")
private String errorMsg;
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import top.charles7c.continew.admin.monitor.enums.LogStatusEnum;
/**
* 操作日志信息
*
* @author Charles7c
* @since 2023/1/14 18:27
*/
@Data
@Schema(description = "操作日志信息")
public class OperationLogResp extends LogResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 操作内容
*/
@Schema(description = "操作内容", example = "新增数据")
private String description;
/**
* 所属模块
*/
@Schema(description = "所属模块", example = "部门管理")
private String module;
/**
* 操作 IP
*/
@Schema(description = "操作 IP", example = "192.168.0.1")
private String ip;
/**
* 操作地点
*/
@Schema(description = "操作地点", example = "中国北京北京市")
private String address;
/**
* 浏览器
*/
@Schema(description = "浏览器", example = "Chrome 115.0.0.0")
private String browser;
/**
* 操作状态
*/
@Schema(description = "操作状态1成功2失败", type = "Integer", allowableValues = {"1", "2"}, example = "1")
private LogStatusEnum status;
/**
* 错误信息
*/
@Schema(description = "错误信息")
private String errorMsg;
}

View File

@@ -1,114 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
/**
* 系统日志详情信息
*
* @author Charles7c
* @since 2023/1/18 20:19
*/
@Data
@Schema(description = "系统日志详情信息")
public class SystemLogDetailResp extends LogResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 链路 ID
*/
@Schema(description = "链路 ID", example = "904846526308876288")
private String traceId;
/**
* 状态码
*/
@Schema(description = "状态码", example = "200")
private Integer statusCode;
/**
* 请求方式
*/
@Schema(description = "请求方式", example = "POST")
private String requestMethod;
/**
* 请求 URL
*/
@Schema(description = "请求 URL", example = "http://api.charles7c.top/system/dept")
private String requestUrl;
/**
* 请求头
*/
@Schema(description = "请求头", example = "{\"Origin\": [\"https://cnadmin.charles7c.top\"],...}")
private String requestHeaders;
/**
* 请求体
*/
@Schema(description = "请求体", example = "{\"name\": \"测试部\",...}")
private String requestBody;
/**
* 响应头
*/
@Schema(description = "响应头", example = "{\"Content-Type\": [\"application/json\"],...}")
private String responseHeaders;
/**
* 响应体
*/
@Schema(description = "响应体", example = "{\"success\":true},...")
private String responseBody;
/**
* IP
*/
@Schema(description = "IP", example = "192.168.0.1")
private String ip;
/**
* 地址
*/
@Schema(description = "地址", example = "中国北京北京市")
private String address;
/**
* 浏览器
*/
@Schema(description = "浏览器", example = "Chrome 115.0.0.0")
private String browser;
/**
* 操作系统
*/
@Schema(description = "操作系统", example = "Windows 10")
private String os;
/**
* 耗时ms
*/
@Schema(description = "耗时ms", example = "58")
private Long timeTaken;
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.model.resp;
import java.io.Serial;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 系统日志信息
*
* @author Charles7c
* @since 2023/1/17 23:29
*/
@Data
@Schema(description = "系统日志信息")
public class SystemLogResp extends LogResp {
@Serial
private static final long serialVersionUID = 1L;
/**
* 状态码
*/
@Schema(description = "状态码", example = "200")
private Integer statusCode;
/**
* 请求方式
*/
@Schema(description = "请求方式", example = "POST")
private String requestMethod;
/**
* 请求 URL
*/
@Schema(description = "请求 URL", example = "http://api.charles7c.top/system/dept")
private String requestUrl;
/**
* IP
*/
@Schema(description = "IP", example = "192.168.0.1")
private String ip;
/**
* 地址
*/
@Schema(description = "地址", example = "中国北京北京市")
private String address;
/**
* 浏览器
*/
@Schema(description = "浏览器", example = "Chrome 115.0.0.0")
private String browser;
/**
* 耗时ms
*/
@Schema(description = "耗时ms", example = "58")
private Long timeTaken;
}

View File

@@ -1,70 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.service;
import java.util.List;
import top.charles7c.continew.admin.monitor.model.resp.DashboardAccessTrendResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardGeoDistributionResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardPopularModuleResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardTotalResp;
import top.charles7c.continew.admin.system.model.resp.DashboardAnnouncementResp;
/**
* 仪表盘业务接口
*
* @author Charles7c
* @since 2023/9/8 21:32
*/
public interface DashboardService {
/**
* 查询总计信息
*
* @return 总计信息
*/
DashboardTotalResp getTotal();
/**
* 查询访问趋势信息
*
* @param days 日期数
* @return 访问趋势信息
*/
List<DashboardAccessTrendResp> listAccessTrend(Integer days);
/**
* 查询热门模块列表
*
* @return 热门模块列表
*/
List<DashboardPopularModuleResp> listPopularModule();
/**
* 查询访客地域分布信息
*
* @return 访客地域分布信息
*/
DashboardGeoDistributionResp getGeoDistribution();
/**
* 查询公告列表
*
* @return 公告列表
*/
List<DashboardAnnouncementResp> listAnnouncement();
}

View File

@@ -1,100 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.service;
import top.charles7c.continew.admin.monitor.model.query.LoginLogQuery;
import top.charles7c.continew.admin.monitor.model.query.OperationLogQuery;
import top.charles7c.continew.admin.monitor.model.query.SystemLogQuery;
import top.charles7c.continew.admin.monitor.model.resp.*;
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
import java.util.List;
import java.util.Map;
/**
* 系统日志业务接口
*
* @author Charles7c
* @since 2022/12/23 20:12
*/
public interface LogService {
/**
* 分页查询操作日志列表
*
* @param query 查询条件
* @param pageQuery 分页查询条件
* @return 操作日志分页信息
*/
PageResp<OperationLogResp> page(OperationLogQuery query, PageQuery pageQuery);
/**
* 分页查询登录日志列表
*
* @param query 查询条件
* @param pageQuery 分页查询条件
* @return 登录日志分页信息
*/
PageResp<LoginLogResp> page(LoginLogQuery query, PageQuery pageQuery);
/**
* 分页查询系统日志列表
*
* @param query 查询条件
* @param pageQuery 分页查询条件
* @return 系统日志分页信息
*/
PageResp<SystemLogResp> page(SystemLogQuery query, PageQuery pageQuery);
/**
* 查看系统日志详情
*
* @param logId 日志 ID
* @return 系统日志详情
*/
SystemLogDetailResp get(Long logId);
/**
* 查询仪表盘总计信息
*
* @return 仪表盘总计信息
*/
DashboardTotalResp getDashboardTotal();
/**
* 查询仪表盘访问趋势信息
*
* @param days 日期数
* @return 仪表盘访问趋势信息
*/
List<DashboardAccessTrendResp> listDashboardAccessTrend(Integer days);
/**
* 查询仪表盘热门模块列表
*
* @return 仪表盘热门模块列表
*/
List<DashboardPopularModuleResp> listDashboardPopularModule();
/**
* 查询仪表盘访客地域分布信息
*
* @return 仪表盘访客地域分布信息
*/
List<Map<String, Object>> listDashboardGeoDistribution();
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import top.charles7c.continew.admin.monitor.model.resp.DashboardAccessTrendResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardGeoDistributionResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardPopularModuleResp;
import top.charles7c.continew.admin.monitor.model.resp.DashboardTotalResp;
import top.charles7c.continew.admin.monitor.service.DashboardService;
import top.charles7c.continew.admin.monitor.service.LogService;
import top.charles7c.continew.admin.system.model.resp.DashboardAnnouncementResp;
import top.charles7c.continew.admin.system.service.AnnouncementService;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* 仪表盘业务实现
*
* @author Charles7c
* @since 2023/9/8 21:32
*/
@Service
@RequiredArgsConstructor
public class DashboardServiceImpl implements DashboardService {
private final LogService logService;
private final AnnouncementService announcementService;
@Override
public DashboardTotalResp getTotal() {
DashboardTotalResp totalResp = logService.getDashboardTotal();
Long todayPvCount = totalResp.getTodayPvCount();
Long yesterdayPvCount = totalResp.getYesterdayPvCount();
BigDecimal newPvCountFromYesterday = NumberUtil.sub(todayPvCount, yesterdayPvCount);
BigDecimal newPvFromYesterday = (0 == yesterdayPvCount)
? BigDecimal.valueOf(100)
: NumberUtil.round(NumberUtil.mul(NumberUtil.div(newPvCountFromYesterday, yesterdayPvCount), 100), 1);
totalResp.setNewPvFromYesterday(newPvFromYesterday);
return totalResp;
}
@Override
public List<DashboardAccessTrendResp> listAccessTrend(Integer days) {
return logService.listDashboardAccessTrend(days);
}
@Override
public List<DashboardPopularModuleResp> listPopularModule() {
List<DashboardPopularModuleResp> popularModuleList = logService.listDashboardPopularModule();
for (DashboardPopularModuleResp popularModule : popularModuleList) {
Long todayPvCount = popularModule.getTodayPvCount();
Long yesterdayPvCount = popularModule.getYesterdayPvCount();
BigDecimal newPvCountFromYesterday = NumberUtil.sub(todayPvCount, yesterdayPvCount);
BigDecimal newPvFromYesterday = (0 == yesterdayPvCount)
? BigDecimal.valueOf(100)
: NumberUtil.round(NumberUtil.mul(NumberUtil.div(newPvCountFromYesterday, yesterdayPvCount), 100), 1);
popularModule.setNewPvFromYesterday(newPvFromYesterday);
}
return popularModuleList;
}
@Override
public DashboardGeoDistributionResp getGeoDistribution() {
List<Map<String, Object>> locationIpStatistics = logService.listDashboardGeoDistribution();
DashboardGeoDistributionResp geoDistribution = new DashboardGeoDistributionResp();
geoDistribution.setLocationIpStatistics(locationIpStatistics);
geoDistribution.setLocations(locationIpStatistics.stream().map(m -> Convert.toStr(m.get("name"))).toList());
return geoDistribution;
}
@Override
public List<DashboardAnnouncementResp> listAnnouncement() {
return announcementService.listDashboard();
}
}

View File

@@ -1,133 +0,0 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package top.charles7c.continew.admin.monitor.service.impl;
import cn.crane4j.annotation.AutoOperate;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.charles7c.continew.admin.common.constant.SysConstants;
import top.charles7c.continew.admin.monitor.mapper.LogMapper;
import top.charles7c.continew.admin.monitor.model.entity.LogDO;
import top.charles7c.continew.admin.monitor.model.query.LoginLogQuery;
import top.charles7c.continew.admin.monitor.model.query.OperationLogQuery;
import top.charles7c.continew.admin.monitor.model.query.SystemLogQuery;
import top.charles7c.continew.admin.monitor.model.resp.*;
import top.charles7c.continew.admin.monitor.service.LogService;
import top.charles7c.continew.starter.core.util.ReflectUtils;
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
import top.charles7c.continew.starter.data.mybatis.plus.query.QueryWrapperHelper;
import top.charles7c.continew.starter.extension.crud.model.query.PageQuery;
import top.charles7c.continew.starter.extension.crud.model.resp.PageResp;
import java.util.List;
import java.util.Map;
/**
* 系统日志业务实现
*
* @author Charles7c
* @since 2022/12/23 20:12
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class LogServiceImpl implements LogService {
private final LogMapper logMapper;
@Override
@AutoOperate(type = OperationLogResp.class, on = "list")
public PageResp<OperationLogResp> page(OperationLogQuery query, PageQuery pageQuery) {
QueryWrapper<LogDO> queryWrapper = QueryWrapperHelper.build(query);
// 限定查询信息
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(OperationLogResp.class);
List<String> columnNameList = fieldNameList.stream()
.filter(n -> !n.endsWith(SysConstants.DESCRIPTION_FIELD_SUFFIX))
.map(StrUtil::toUnderlineCase)
.toList();
queryWrapper.select(columnNameList);
// 分页查询
IPage<LogDO> page = logMapper.selectPage(pageQuery.toPage(), queryWrapper);
return PageResp.build(page, OperationLogResp.class);
}
@Override
@AutoOperate(type = LoginLogResp.class, on = "list")
public PageResp<LoginLogResp> page(LoginLogQuery query, PageQuery pageQuery) {
QueryWrapper<LogDO> queryWrapper = QueryWrapperHelper.build(query);
queryWrapper.eq("module", "登录");
// 限定查询信息
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(LoginLogResp.class);
List<String> columnNameList = fieldNameList.stream()
.filter(n -> !n.endsWith(SysConstants.DESCRIPTION_FIELD_SUFFIX))
.map(StrUtil::toUnderlineCase)
.toList();
queryWrapper.select(columnNameList);
// 分页查询
IPage<LogDO> page = logMapper.selectPage(pageQuery.toPage(), queryWrapper);
return PageResp.build(page, LoginLogResp.class);
}
@Override
@AutoOperate(type = SystemLogResp.class, on = "list")
public PageResp<SystemLogResp> page(SystemLogQuery query, PageQuery pageQuery) {
QueryWrapper<LogDO> queryWrapper = QueryWrapperHelper.build(query);
// 限定查询信息
List<String> fieldNameList = ReflectUtils.getNonStaticFieldsName(SystemLogResp.class);
List<String> columnNameList = fieldNameList.stream()
.filter(n -> !n.endsWith(SysConstants.DESCRIPTION_FIELD_SUFFIX))
.map(StrUtil::toUnderlineCase)
.toList();
queryWrapper.select(columnNameList);
// 分页查询
IPage<LogDO> page = logMapper.selectPage(pageQuery.toPage(), queryWrapper);
return PageResp.build(page, SystemLogResp.class);
}
@Override
@AutoOperate(type = SystemLogDetailResp.class)
public SystemLogDetailResp get(Long id) {
LogDO logDO = logMapper.selectById(id);
CheckUtils.throwIfNotExists(logDO, "LogDO", "ID", id);
return BeanUtil.copyProperties(logDO, SystemLogDetailResp.class);
}
@Override
public DashboardTotalResp getDashboardTotal() {
return logMapper.selectDashboardTotal();
}
@Override
public List<DashboardAccessTrendResp> listDashboardAccessTrend(Integer days) {
return logMapper.selectListDashboardAccessTrend(days);
}
@Override
public List<DashboardPopularModuleResp> listDashboardPopularModule() {
return logMapper.selectListDashboardPopularModule();
}
@Override
public List<Map<String, Object>> listDashboardGeoDistribution() {
return logMapper.selectListDashboardGeoDistribution();
}
}

View File

@@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="top.charles7c.continew.admin.monitor.mapper.LogMapper">
<select id="selectDashboardTotal" resultType="top.charles7c.continew.admin.monitor.model.resp.DashboardTotalResp">
SELECT
(SELECT COUNT(*) FROM sys_log) AS pvCount,
(SELECT COUNT(DISTINCT ip) FROM sys_log) AS ipCount,
(SELECT COUNT(*) FROM sys_log WHERE DATE(create_time) = CURRENT_DATE) AS todayPvCount,
(SELECT COUNT(*) FROM sys_log WHERE DATE(create_time) = CURRENT_DATE - 1) AS yesterdayPvCount
</select>
<select id="selectListDashboardAccessTrend"
resultType="top.charles7c.continew.admin.monitor.model.resp.DashboardAccessTrendResp">
SELECT
DATE(create_time) AS date,
COUNT(*) AS pvCount,
COUNT(DISTINCT ip) AS ipCount
FROM sys_log
WHERE DATE(create_time) != CURRENT_DATE
GROUP BY DATE(create_time)
ORDER BY DATE(create_time) DESC
LIMIT #{days}
</select>
<select id="selectListDashboardPopularModule"
resultType="top.charles7c.continew.admin.monitor.model.resp.DashboardPopularModuleResp">
SELECT
module,
COUNT(*) AS pvCount,
SUM(CASE WHEN DATE(create_time) = CURRENT_DATE THEN 1 ELSE 0 END) AS todayPvCount,
SUM(CASE WHEN DATE(create_time) = CURRENT_DATE - 1 THEN 1 ELSE 0 END) AS yesterdayPvCount
FROM sys_log
WHERE module != '验证码' AND module != '登录'
GROUP BY module
ORDER BY pvCount DESC
LIMIT 10
</select>
<select id="selectListDashboardGeoDistribution" resultType="java.util.Map">
SELECT
CASE
WHEN POSITION(' ' IN address) > 0 THEN SUBSTRING(address FROM 1 FOR POSITION(' ' IN address) - 1)
ELSE address
END AS name,
COUNT(DISTINCT ip) AS value
FROM sys_log
GROUP BY name
ORDER BY value DESC
LIMIT 10
</select>
</mapper>