用户行为分析,数据基础信息新增字段,设计图纸和资料文件列表查询,水库月核定生态流量查询,水库责任体系新增修改

master
徐杰盟 2024-08-13 15:03:45 +08:00
parent eb1168223f
commit abce68b34b
23 changed files with 1047 additions and 4 deletions

View File

@ -2,6 +2,7 @@ package com.gunshi.project.xyt.controller;
import com.gunshi.core.result.R;
import com.gunshi.project.xyt.model.AttResBase;
import com.gunshi.project.xyt.model.FileAssociations;
import com.gunshi.project.xyt.service.AttResBaseService;
import com.gunshi.project.xyt.service.FileAssociationsService;
import com.gunshi.project.xyt.validate.markers.Insert;
@ -18,6 +19,7 @@ import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* :
@ -98,6 +100,18 @@ public class AttResBaseController extends AbstractCommonFileController {
return R.ok(list);
}
@Operation(summary = "设计图纸和资料列表")
@GetMapping("/fileList/{resCode}")
public R<List<FileAssociations>> list(@PathVariable("resCode") String resCode) {
List<FileAssociations> files = fileService.getFiles(getGroupId(), resCode);
if (CollectionUtils.isEmpty(files)){
return R.ok(files);
}
List<FileAssociations> datas = files.stream().filter(o -> "1".equals(o.getType()))
.collect(Collectors.toList());
return R.ok(datas);
}
// @Operation(summary = "分页")
// @PostMapping("/page")
public R<List<AttResBase>> page() {

View File

@ -62,7 +62,7 @@ public class ResMonthEcoFlowController {
@Operation(summary = "列表")
@PostMapping("/list")
public R<List<ResMonthEcoFlow>> list(@Validated ResMonthEcoFlowListSo vo) {
public R<List<ResMonthEcoFlow>> list(@Validated @RequestBody ResMonthEcoFlowListSo vo) {
LocalDateTime stm = LocalDateTime.of(vo.getYear(), 1, 1, 0, 0, 0);
LocalDateTime etm = LocalDateTime.of(vo.getYear(), 12, 31, 23, 59, 59);
return R.ok(service.lambdaQuery().between(ResMonthEcoFlow::getModitime,stm,etm).orderByAsc(ResMonthEcoFlow::getMonth).list());

View File

@ -21,6 +21,7 @@ public interface FileAssociationsMapper extends BaseMapper<FileAssociations> {
SELECT
fa.*,
fd.file_name,
fd.file_size,
fd.file_path
FROM
file_associations fa

View File

@ -493,6 +493,34 @@ public class AttResBase implements Serializable {
@Schema(description="堰顶高程,m")
private BigDecimal wcrstel;
/**
* feedPop
*/
@TableField(value="feed_pop")
@Schema(description="受益人口(人)")
private Integer feedPop;
/**
* design_irr_area
*/
@TableField(value="design_irr_area")
@Schema(description="设计灌溉面积(亩)")
private Integer designIrrArea;
/**
* actual_irr_area
*/
@TableField(value="actual_irr_area")
@Schema(description="实际灌溉面积(亩)")
private BigDecimal actualIrrArea;
/**
* actual_irr_area
*/
@TableField(value="benefit")
@Schema(description="供水效益")
private String benefit;
@TableField(exist = false)
@Schema(description = "文件集合")

View File

@ -104,4 +104,8 @@ public class FileAssociations implements Serializable {
@Schema(description = "文件名称")
private String fileName;
@TableField(exist = false)
@Schema(description = "文件大小 (byte)")
private String fileSize;
}

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.gunshi.core.dateformat.DateFormatString;
import com.gunshi.project.xyt.validate.markers.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@ -35,7 +36,7 @@ public class ResSafePersonB implements Serializable {
@TableId(value="id", type= IdType.AUTO)
@Schema(description="主键")
// @Size(max = 0,message = "主键最大长度要小于 0")
@NotNull(message = "主键不能为空")
@NotNull(message = "主键不能为空",groups = {Update.class})
private Long id;
/**

View File

@ -51,7 +51,7 @@ public class FileAssociationsService extends ServiceImpl<FileAssociationsMapper,
.filter(fileAssociations -> !fileIds.remove(fileAssociations.getFileId()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(files)) {
// if (CollectionUtils.isNotEmpty(files)) {
// 删除
if (this.lambdaUpdate()
@ -63,7 +63,7 @@ public class FileAssociationsService extends ServiceImpl<FileAssociationsMapper,
log.info("delete file {} success!", fileIds);
}
}
// }
}

View File

@ -0,0 +1,247 @@
package com.gunshi.project.xyt.system;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.annotation.Get;
import com.gunshi.core.annotation.Post;
import com.gunshi.core.result.R;
import com.gunshi.project.xyt.system.model.SysUserLoginLog;
import com.gunshi.project.xyt.system.model.SysVisitMenuLog;
import com.gunshi.project.xyt.system.mapper.SysUserLoginLogMapper;
import com.gunshi.project.xyt.system.mapper.SysVisitMenuLogMapper;
import com.gunshi.project.xyt.system.so.UserLoginLogPageSo;
import com.gunshi.project.xyt.system.so.UserLoginLogSo;
import com.gunshi.project.xyt.system.vo.TodayCountVo;
import com.gunshi.project.xyt.system.vo.UserCountVo;
import com.gunshi.project.xyt.system.vo.VisitCountVo;
import com.gunshi.project.xyt.util.DateUtil;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* Description:
* Created by XuSan on 2024/6/20.
*
* @author XuSan
* @version 1.0
*/
@RestController
@RequestMapping("/userLoginLog")
@Tag(name = "用户访问记录")
public class SysUserLoginLogController {
@Autowired
private SysUserLoginLogMapper thisMapper;
@Autowired
private SysVisitMenuLogMapper thisMenuMapper;
// @Autowired
// private ProjectCommonService projectCommonService;
@Post(path = "/page", summary = "分页查询")
public R<Page<SysUserLoginLog>> page(@RequestBody @Validated UserLoginLogPageSo dto) {
LambdaQueryWrapper<SysUserLoginLog> queryWrapper = Wrappers.lambdaQuery();
if (dto.getName() != null) {
queryWrapper.eq(SysUserLoginLog::getCreateId, dto.getName());
}
return R.ok(thisMapper.selectPage(dto.getPageSo().toPage(), queryWrapper));
}
@Get(path = "/todayCount", summary = "今日数据总览")
public R<TodayCountVo> todayCount() {
LambdaQueryWrapper<SysUserLoginLog> wrapper = Wrappers.lambdaQuery(SysUserLoginLog.class)
.between(SysUserLoginLog::getCreateDate, DateUtil.convertStringToDate(LocalDate.now().toString() + " 00:00:00"), new Date());
List<SysUserLoginLog> logs = thisMapper.selectList(wrapper);
if (CollectionUtils.isEmpty(logs)) {
return R.ok(null);
}
TodayCountVo vo = new TodayCountVo();
vo.setWeb1Count(
logs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.count());
List<Long> webTimes = logs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.filter(o -> o.getLogoutTime() != null && o.getLoginTime() != null)
.map(o -> o.getLogoutTime().getTime() - o.getLoginTime().getTime())
.collect(Collectors.toList());
BigDecimal divisor = BigDecimal.valueOf(1000 * 60 * 60);
vo.setWeb3Count(
BigDecimal.valueOf(webTimes.stream().mapToLong(o -> o).sum())
.divide(BigDecimal.valueOf(webTimes.size()), 2, RoundingMode.HALF_UP)
.divide(divisor, 2, RoundingMode.HALF_UP)
);
vo.setApp1Count(
logs.stream()
.filter(o -> "1".equals(o.getLoginType()))
.count()
);
List<Long> appTimes = logs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.filter(o -> o.getLogoutTime() != null && o.getLoginTime() != null)
.map(o -> o.getLogoutTime().getTime() - o.getLoginTime().getTime())
.collect(Collectors.toList());
vo.setApp3Count(
BigDecimal.valueOf(appTimes.stream().mapToLong(o -> o).sum())
.divide(BigDecimal.valueOf(appTimes.size()),2, RoundingMode.HALF_UP)
.divide(divisor,2, RoundingMode.HALF_UP)
);
LambdaQueryWrapper<SysVisitMenuLog> wrapperMenuLog = Wrappers.lambdaQuery(SysVisitMenuLog.class)
.eq(SysVisitMenuLog::getCreateTime, new Date());
vo.setWeb2Count(0L);
vo.setApp2Count(0L);
List<SysVisitMenuLog> wrapperMenuLogs = thisMenuMapper.selectList(wrapperMenuLog);
if (CollectionUtils.isNotEmpty(wrapperMenuLogs)) {
vo.setWeb2Count(
wrapperMenuLogs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.count()
);
vo.setApp2Count(
wrapperMenuLogs.stream()
.filter(o -> "1".equals(o.getLoginType()))
.count()
);
}
return R.ok(vo);
}
@Post(path = "/visitCount", summary = "访问用户前十")
public R<VisitCountVo> visitCount(@RequestBody @Validated UserLoginLogSo so) {
List<SysUserLoginLog> logs = thisMapper.getUserLoginLog(so.getStm(), so.getEtm());
VisitCountVo vo = new VisitCountVo();
if (CollectionUtils.isEmpty(logs)) {
return R.ok(vo);
}
vo.setWebList(logs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.collect(Collectors.groupingBy(SysUserLoginLog::getUserName, Collectors.counting()))
.entrySet().stream()
.map(o -> {
VisitCountVo.VisitCountDataVo dataVo = new VisitCountVo.VisitCountDataVo();
dataVo.setCount(o.getValue());
dataVo.setName(o.getKey());
return dataVo;
}).collect(Collectors.toList())
);
vo.setAppList(logs.stream()
.filter(o -> "1".equals(o.getLoginType()))
.collect(Collectors.groupingBy(SysUserLoginLog::getUserName, Collectors.counting()))
.entrySet().stream()
.map(o -> {
VisitCountVo.VisitCountDataVo dataVo = new VisitCountVo.VisitCountDataVo();
dataVo.setCount(o.getValue());
dataVo.setName(o.getKey());
return dataVo;
})
.limit(10)
.collect(Collectors.toList())
);
return R.ok(vo);
}
@Post(path = "/userCount", summary = "日活跃用户数")
public R<UserCountVo> userCount(@RequestBody @Validated UserLoginLogSo so) {
List<SysUserLoginLog> logs = thisMapper.getUserLoginLog(so.getStm(), so.getEtm());
UserCountVo vo = new UserCountVo();
if (CollectionUtils.isEmpty(logs)) {
return R.ok(vo);
}
vo.setWebList(logs.stream()
.filter(o -> "0".equals(o.getLoginType()))
.collect(Collectors.groupingBy(SysUserLoginLog::getCreateDate, Collectors.counting()))
.entrySet().stream()
.map(o -> {
UserCountVo.UserCountDataVo dataVo = new UserCountVo.UserCountDataVo();
dataVo.setCount(o.getValue());
dataVo.setCreateDate(o.getKey());
return dataVo;
}).collect(Collectors.toList())
);
vo.setAppList(logs.stream()
.filter(o -> "1".equals(o.getLoginType()))
.collect(Collectors.groupingBy(SysUserLoginLog::getCreateDate, Collectors.counting()))
.entrySet().stream()
.map(o -> {
UserCountVo.UserCountDataVo dataVo = new UserCountVo.UserCountDataVo();
dataVo.setCount(o.getValue());
dataVo.setCreateDate(o.getKey());
return dataVo;
}).collect(Collectors.toList())
);
return R.ok(vo);
}
@Post(path = "/insert", summary = "添加")
public R<Boolean> insert(@RequestBody @Validated SysUserLoginLog dto) {
if (Objects.isNull(dto.getCreateId())) {
// Long loginUserId = projectCommonService.getLoginUserId();
// dto.setCreateId(loginUserId);
}
// 查询当前时间是否存在
List<SysUserLoginLog> uLogs = thisMapper.selectList(
Wrappers
.lambdaQuery(SysUserLoginLog.class)
.eq(SysUserLoginLog::getCreateId,dto.getCreateId())
.eq(SysUserLoginLog::getCreateDate, new Date()));
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(uLogs)) {
throw new RuntimeException("当前数据已存在");
}
Date date = new Date();
// 第一次登录
dto
.setCreateDate(date)
.setLoginTime(date)
.setLogoutTime(date);
return R.ok(thisMapper.insert(dto) == 1);
}
}

View File

@ -0,0 +1,104 @@
package com.gunshi.project.xyt.system;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gunshi.core.annotation.Post;
import com.gunshi.core.result.R;
import com.gunshi.core.result.exception.NeedLoginException;
import com.gunshi.project.xyt.system.model.SysVisitMenuLog;
import com.gunshi.project.xyt.system.mapper.SysVisitMenuLogMapper;
import com.gunshi.project.xyt.system.so.VisitMenuLogPageSo;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* Description:
* Created by XuSan on 2024/6/20.
*
* @author XuSan
* @version 1.0
*/
@Slf4j
@RestController
@RequestMapping("/visitMenuLog")
@Tag(name = "页面访问记录")
public class SysVisitMenuLogController {
@Autowired
private SysVisitMenuLogMapper thisMapper;
// @Resource
// private ProjectCommonService projectCommonService;
@Post(path = "/page", summary = "分页查询")
public R<Page<SysVisitMenuLog>> page(@RequestBody @Validated VisitMenuLogPageSo dto) {
LambdaQueryWrapper<SysVisitMenuLog> queryWrapper = Wrappers.lambdaQuery();
if (dto.getMenu() != null) {
queryWrapper.like(SysVisitMenuLog::getMenu1, dto.getMenu());
queryWrapper.like(SysVisitMenuLog::getMenu2, dto.getMenu());
queryWrapper.like(SysVisitMenuLog::getMenu3, dto.getMenu());
}
return R.ok(thisMapper.selectPage(dto.getPageSo().toPage(), queryWrapper));
}
@Post(path = "/count", summary = "统计查询")
public R<List<SysVisitMenuLog>> count(@RequestBody @Validated VisitMenuLogPageSo dto) {
LambdaQueryWrapper<SysVisitMenuLog> queryWrapper = Wrappers.query(SysVisitMenuLog.class)
.select("COUNT(ID) COUNT, menu2, menu1")
.lambda();
if (dto.getStm() != null) {
queryWrapper.ge(SysVisitMenuLog::getCreateTime, dto.getStm());
}
if (dto.getEtm() != null) {
queryWrapper.le(SysVisitMenuLog::getCreateTime, dto.getEtm());
}
queryWrapper.groupBy(SysVisitMenuLog::getMenu2, SysVisitMenuLog::getMenu1);
List<SysVisitMenuLog> list = thisMapper.selectList(queryWrapper);
return R.ok(
list
.stream()
.sorted(
Comparator
.comparing(SysVisitMenuLog::getCount)
.reversed()
)
.collect(Collectors.toList())
);
}
@Post(path = "/insert", summary = "添加")
public R<Boolean> insert(@RequestBody @Validated SysVisitMenuLog dto) {
Long loginUserId = null;
// 获取用户id
try {
// loginUserId = projectCommonService.getLoginUserId();
} catch (NeedLoginException e) {
log.info("获取登录账号id," + e.getMessage(), e);
}
// if (null == dto.getCreateId() && null != loginUserId){
// dto.setCreateId(loginUserId);
// }
return R.ok(thisMapper.insert(dto) == 1);
}
}

View File

@ -0,0 +1,119 @@
package com.gunshi.project.xyt.system.aspect;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gunshi.core.result.exception.NeedLoginException;
import com.gunshi.project.xyt.system.model.SysUserLoginLog;
import com.gunshi.project.xyt.system.mapper.SysUserLoginLogMapper;
import com.gunshi.project.xyt.system.utils.ReqUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* Description:
* Created by XuSan on 2024/6/20.
*
* @author XuSan
* @version 1.0
*/
@Aspect
@Slf4j
@Component
public class SysUserLogAspect {
@Autowired
private SysUserLoginLogMapper userLoginLogMapper;
// @Autowired
// private ProjectCommonService projectCommonService;
@Pointcut("execution(public * com.gunshi.project.xyt.controller..*Controller.*(..))")
public void controllerPointcut() {
}
@Before("controllerPointcut()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
log.info("进入记录日志切面");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Long loginUserId = null;
// 获取用户id
try {
// loginUserId = projectCommonService.getLoginUserId();
} catch (NeedLoginException e) {
log.info("获取登录账号id," + e.getMessage(), e);
}
if (loginUserId != null) {
String loginType = request.getHeader("loginType");
if (StringUtils.isBlank(loginType)){
loginType = "0";
}
// 查询当前时间是否存在
List<SysUserLoginLog> uLogs = userLoginLogMapper.selectList(
Wrappers
.lambdaQuery(SysUserLoginLog.class)
.eq(SysUserLoginLog::getLoginType, loginType)
.eq(SysUserLoginLog::getCreateDate, new Date())
.eq(SysUserLoginLog::getCreateId, loginUserId));
Integer id = null;
SysUserLoginLog o = new SysUserLoginLog();
if (CollectionUtils.isNotEmpty(uLogs)) {
o = uLogs.getFirst();
id = o.getId();
}
Date date = new Date();
if (Objects.isNull(id)) {
String ip = request.getHeader("ClientIp");
if (StringUtils.isBlank(ip)) {
ip = ReqUtil.getIpAddress(request);
}
// 第一次登录
o.setLoginType(loginType);
o.setCreateId(loginUserId)
.setCreateDate(date)
.setLoginTime(date)
.setIp(ip)
.setLogoutTime(date);
if (userLoginLogMapper.insert(o) != 1) {
log.error("插入用户登录日志失败");
}
} else {
o.setId(id);
o.setLogoutTime(date);
if (userLoginLogMapper.updateById(o) != 1) {
log.error("更新用户登录日志失败");
}
}
}
log.info("记录日志切面结束");
}
}

View File

@ -0,0 +1,24 @@
package com.gunshi.project.xyt.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.xyt.system.model.SysUserLoginLog;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Date;
import java.util.List;
@Mapper
public interface SysUserLoginLogMapper extends BaseMapper<SysUserLoginLog> {
@Select("""
<script>
SELECT su.*,ub.user_name
FROM sys_user_login_log su LEFT JOIN uams_user_b ub on su.createId = ub.user_id
WHERE su.create_date between #{stm} and #{etm}
</script>
""")
List<SysUserLoginLog> getUserLoginLog(@Param("stm") Date stm , @Param("etm") Date etm);
}

View File

@ -0,0 +1,9 @@
package com.gunshi.project.xyt.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gunshi.project.xyt.system.model.SysVisitMenuLog;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface SysVisitMenuLogMapper extends BaseMapper<SysVisitMenuLog> {
}

View File

@ -0,0 +1,66 @@
package com.gunshi.project.xyt.system.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.gunshi.core.dateformat.DateFormatString;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
*
*/
@Schema(description="用户登录日志")
@Data
@TableName(value = "public.sys_user_login_log")
@Accessors(chain = true)
public class SysUserLoginLog implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description="主键id")
@JsonSerialize(using = ToStringSerializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Integer id;
@TableField(value = "create_id")
@Schema(description="用户编号")
private Long createId;
@TableField(value = "login_type")
@Schema(description="登录类型, 0: web, 1:app")
private String loginType;
@TableField(value = "ip")
@Schema(description="ip")
private String ip;
@TableField(value = "create_date")
@Schema(description="日期")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
private Date createDate;
@TableField(value = "login_time")
@Schema(description="登录时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date loginTime;
@TableField(value = "logout_time")
@Schema(description="登出时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date logoutTime;
@TableField(exist = false)
@Schema(description="用户名称")
private String userName;
}

View File

@ -0,0 +1,60 @@
package com.gunshi.project.xyt.system.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.gunshi.core.dateformat.DateFormatString;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
*
*/
@Schema(description="菜单访问日志")
@Data
@TableName(value = "public.sys_visit_menu_log")
public class SysVisitMenuLog implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
@Schema(description="主键id")
@JsonSerialize(using = ToStringSerializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Integer id;
@TableField(value = "create_id")
@Schema(description="用户编号")
private Long createId;
@TableField(value = "login_type")
@Schema(description="登录类型, 0: web, 1:app")
private String loginType;
@TableField(value = "create_time")
@Schema(description="创建时间")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD_HH_MM_SS, timezone = "GMT+8")
private Date createTime;
@TableField(value = "menu1")
@Schema(description="菜单1")
private String menu1;
@TableField(value = "menu2")
@Schema(description="菜单2")
private String menu2;
@TableField(value = "menu3")
@Schema(description="菜单3")
private String menu3;
@TableField(exist = false)
@Schema(description="统计数量")
private String count;
}

View File

@ -0,0 +1,34 @@
package com.gunshi.project.xyt.system.so;
import com.gunshi.db.dto.PageSo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
/**
*
* Created by wanyan on 2024/4/7.
*
* @author wanyan
* @version 1.0
*/
@Data
@Schema(description = "用户访问记录分页查询条件")
public class UserLoginLogPageSo {
@NotNull(message = "分页参数不能为空")
@Schema(description = "分页参数")
private PageSo pageSo;
@Schema(description="名称")
private String name;
@Schema(description="开始时间 yyyy-MM-dd HH:mm:ss")
private Date stm;
@Schema(description="结束时间 yyyy-MM-dd HH:mm:ss")
private Date etm;
}

View File

@ -0,0 +1,29 @@
package com.gunshi.project.xyt.system.so;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
/**
*
* Created by wanyan on 2024/4/7.
*
* @author wanyan
* @version 1.0
*/
@Data
@Schema(description = "用户访问记录统计查询条件")
public class UserLoginLogSo {
@Schema(description="开始时间 yyyy-MM-dd HH:mm:ss")
@NotNull
private Date stm;
@Schema(description="结束时间 yyyy-MM-dd HH:mm:ss")
@NotNull
private Date etm;
}

View File

@ -0,0 +1,37 @@
package com.gunshi.project.xyt.system.so;
import com.gunshi.db.dto.PageSo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
/**
*
* Created by wanyan on 2024/4/7.
*
* @author wanyan
* @version 1.0
*/
@Data
@Schema(description = "页面访问记录分页查询条件")
public class VisitMenuLogPageSo {
@NotNull(message = "分页参数不能为空")
@Schema(description = "分页参数")
private PageSo pageSo;
@Schema(description="菜单名")
private String menu;
@Schema(description="名称")
private String name;
@Schema(description="开始时间 yyyy-MM-dd HH:mm:ss")
private Date stm;
@Schema(description="结束时间 yyyy-MM-dd HH:mm:ss")
private Date etm;
}

View File

@ -0,0 +1,150 @@
package com.gunshi.project.xyt.system.utils;
import jakarta.servlet.http.HttpServletRequest;
public class ReqUtil {
// private static DbConfig config = null;
private static String dbPath = null;
// private static DbSearcher searcher = null;
/**
* IP使request.getRemoteAddr();使IP,
* X-Forwarded-ForIPIP
* X-Forwarded-ForunknownIP
* X-Forwarded-For192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100
* IP 192.168.1.110
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {// 获取客户端ip地址
String clientIp = request.getHeader("x-forwarded-for");
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("Proxy-Client-IP");
}
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("WL-Proxy-Client-IP");
}
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr();
}
/*
* ipip.
*/
String sIP = null;
if (clientIp != null && !clientIp.contains("unknown") && clientIp.indexOf(",") > 0) {
String[] ipsz = clientIp.split(",");
for (String anIpsz : ipsz) {
if (!isInnerIP(anIpsz.trim())) {
sIP = anIpsz.trim();
break;
}
}
/*
* ipipip.
*/
if (null == sIP) {
sIP = ipsz[0].trim();
}
clientIp = sIP;
}
if (clientIp != null && clientIp.contains("unknown")) {
clientIp = clientIp.replaceAll("unknown,", "");
clientIp = clientIp.trim();
}
if ("".equals(clientIp) || null == clientIp) {
clientIp = "127.0.0.1";
}
return clientIp;
}
/**
* IP
*
* @param ipAddress ip
* @return
*/
public static boolean isInnerIP(String ipAddress) {
boolean isInnerIp;
long ipNum = getIpNum(ipAddress);
/**
IPA 10.0.0.0-10.255.255.255
B 172.16.0.0-172.31.255.255
C 192.168.0.0-192.168.255.255
127
**/
long aBegin = getIpNum("10.0.0.0");
long aEnd = getIpNum("10.255.255.255");
long bBegin = getIpNum("172.16.0.0");
long bEnd = getIpNum("172.31.255.255");
long cBegin = getIpNum("192.168.0.0");
long cEnd = getIpNum("192.168.255.255");
isInnerIp =
isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1");
return isInnerIp;
}
private static long getIpNum(String ipAddress) {
String[] ip = ipAddress.split("\\.");
long a = Integer.parseInt(ip[0]);
long b = Integer.parseInt(ip[1]);
long c = Integer.parseInt(ip[2]);
long d = Integer.parseInt(ip[3]);
return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
}
private static boolean isInner(long userIp, long begin, long end) {
return (userIp >= begin) && (userIp <= end);
}
public static String getRealIP(HttpServletRequest request) {
// 获取客户端ip地址
String clientIp = request.getHeader("x-forwarded-for");
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr();
}
String[] clientIps = clientIp.split(",");
if (clientIps.length <= 1) return clientIp.trim();
// 判断是否来自CDN
if (isComefromCDN(request)) {
if (clientIps.length >= 2) return clientIps[clientIps.length - 2].trim();
}
return clientIps[clientIps.length - 1].trim();
}
private static boolean isComefromCDN(HttpServletRequest request) {
String host = request.getHeader("host");
return host.contains("www.189.cn") || host.contains("shouji.189.cn") || host.contains("image2.chinatelecom-ec" +
".com") || host.contains("image1.chinatelecom-ec.com");
}
// public static synchronized String getRegion(String ip) {
// if (StrKit.isBlank(ip)) return null;
// boolean isIpAddress = Util.isIpAddress(ip);
// if (!isIpAddress) return null;
// try {
// if (searcher == null) {
// if (null == config) config = new DbConfig();
// if (null == dbPath) dbPath = ReqUtil.class.getResource("/ip2region/ip2region.db").getPath();
// searcher = new DbSearcher(config, dbPath);
// }
//
// DataBlock dataBlock = searcher.binarySearch(ip);
// return dataBlock.getRegion();
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// return null;
// }
}

View File

@ -0,0 +1,36 @@
package com.gunshi.project.xyt.system.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
/**
* Description:
* Created by XuSan on 2024/6/25.
*
* @author XuSan
* @version 1.0
*/
@Data
public class TodayCountVo {
@Schema(description = "WEB端访问次数")
private Long web1Count;
@Schema(description = "WEB端浏览次数")
private Long web2Count;
@Schema(description = "WEB端平均访问时长")
private BigDecimal web3Count;
@Schema(description = "移动端访问次数")
private Long app1Count;
@Schema(description = "移动端浏览次数")
private Long app2Count;
@Schema(description = "移动端平均访问时长")
private BigDecimal app3Count;
}

View File

@ -0,0 +1,37 @@
package com.gunshi.project.xyt.system.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.gunshi.core.dateformat.DateFormatString;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* Description:
* Created by XuSan on 2024/6/25.
*
* @author XuSan
* @version 1.0
*/
@Data
public class UserCountVo {
@Schema(description = "web统计数据")
private List<UserCountDataVo> webList;
@Schema(description = "app统计数据")
private List<UserCountDataVo> appList;
@Data
public static class UserCountDataVo {
@Schema(description="日期")
@JsonFormat(pattern = DateFormatString.YYYY_MM_DD, timezone = "GMT+8")
private Date createDate;
@Schema(description = "统计数据")
private Long count;
}
}

View File

@ -0,0 +1,33 @@
package com.gunshi.project.xyt.system.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
/**
* Description:
* Created by XuSan on 2024/6/25.
*
* @author XuSan
* @version 1.0
*/
@Data
public class VisitCountVo {
@Schema(description = "web统计数据")
private List<VisitCountDataVo> webList;
@Schema(description = "app统计数据")
private List<VisitCountDataVo> appList;
@Data
public static class VisitCountDataVo {
@Schema(description = "名字")
private String name;
@Schema(description = "统计数据")
private Long count;
}
}

View File

@ -0,0 +1,5 @@
<?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="com.gunshi.project.xf.flood.controller.system.mapper.SysUserLoginLogMapper">
</mapper>

View File

@ -0,0 +1,5 @@
<?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="com.gunshi.project.xf.flood.controller.system.mapper.SysVisitMenuLogMapper">
</mapper>