提交 80e40c16 作者: 洪东保

用户登录统计及导出

父级 82f6e4d5
...@@ -88,11 +88,11 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter { ...@@ -88,11 +88,11 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests() .authorizeRequests()
// 对于登录login 图标 要允许匿名访问 // 对于登录login 图标 要允许匿名访问
// .antMatchers(customApi).access("@robotJwtCustomTokenFilter.checkToken(request)") // .antMatchers(customApi).access("@robotJwtCustomTokenFilter.checkToken(request)")
.antMatchers("/agent/auth/**").anonymous()
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css", .antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css",
"/**/*.js", "/**/*.map") "/**/*.js", "/**/*.map")
.permitAll() .permitAll()
.antMatchers("/error").anonymous() .antMatchers("/error").anonymous()
.antMatchers("/agent/auth/**").anonymous()
.antMatchers("/user/login").anonymous() .antMatchers("/user/login").anonymous()
.antMatchers("/user/userAuth").anonymous() .antMatchers("/user/userAuth").anonymous()
.antMatchers("/user/tokenAuth").anonymous() .antMatchers("/user/tokenAuth").anonymous()
......
...@@ -59,12 +59,12 @@ public class RobotJwtAuthenticationTokenFilter extends OncePerRequestFilter { ...@@ -59,12 +59,12 @@ public class RobotJwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// 检查请求路径是否在白名单中 // // 检查请求路径是否在白名单中
String requestURI = request.getRequestURI(); // String requestURI = request.getRequestURI();
if (isWhiteListPath(requestURI)) { // if (isWhiteListPath(requestURI)) {
chain.doFilter(request, response); // 放行,不验证JWT // chain.doFilter(request, response); // 放行,不验证JWT
return; // return;
} // }
String token = jwtUtil.getToken(request); String token = jwtUtil.getToken(request);
if (StringUtils.isNotBlank(token)) { if (StringUtils.isNotBlank(token)) {
......
...@@ -15,6 +15,8 @@ import com.cmeeting.exception.RobotBaseException; ...@@ -15,6 +15,8 @@ import com.cmeeting.exception.RobotBaseException;
import com.cmeeting.mapper.primary.AuthMapper; import com.cmeeting.mapper.primary.AuthMapper;
import com.cmeeting.mapper.primary.SysUserSyncMapper; import com.cmeeting.mapper.primary.SysUserSyncMapper;
import com.cmeeting.pojo.CoreModulePermissions; import com.cmeeting.pojo.CoreModulePermissions;
import com.cmeeting.pojo.UserAccessRecord;
import com.cmeeting.service.IUserAccessRecordService;
import com.cmeeting.util.*; import com.cmeeting.util.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
...@@ -31,10 +33,7 @@ import java.time.Duration; ...@@ -31,10 +33,7 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
...@@ -69,6 +68,8 @@ public class UserServiceImpl implements UserService { ...@@ -69,6 +68,8 @@ public class UserServiceImpl implements UserService {
private AuthMapper authMapper; private AuthMapper authMapper;
@Resource @Resource
private SysUserSyncMapper sysUserSyncMapper; private SysUserSyncMapper sysUserSyncMapper;
@Resource
private IUserAccessRecordService iUserAccessRecordService;
@Override @Override
public R login(String agentId, String data, String ip) { public R login(String agentId, String data, String ip) {
...@@ -93,6 +94,8 @@ public class UserServiceImpl implements UserService { ...@@ -93,6 +94,8 @@ public class UserServiceImpl implements UserService {
String token = jwtUtil.generateToken(userDetail); String token = jwtUtil.generateToken(userDetail);
redisUtils.set(token, userDetail, Long.parseLong(expireTime)); redisUtils.set(token, userDetail, Long.parseLong(expireTime));
// 记录登录日志
iUserAccessRecordService.save(UserAccessRecord.builder().userId(userId).createTime(new Date()).build());
return token; return token;
} }
......
...@@ -78,9 +78,6 @@ public class JwtUtil { ...@@ -78,9 +78,6 @@ public class JwtUtil {
*/ */
public String getToken(HttpServletRequest request) { public String getToken(HttpServletRequest request) {
String token = request.getHeader(tokenHeader); String token = request.getHeader(tokenHeader);
if (StrUtil.isBlank(token)) {
throw new RobotBaseException("认证已过期!", 401);
}
if (StrUtil.isNotBlank(token) && token.length() > authTokenStart.length()) { if (StrUtil.isNotBlank(token) && token.length() > authTokenStart.length()) {
token = token.substring(authTokenStart.length()).trim(); token = token.substring(authTokenStart.length()).trim();
} }
......
package com.cmeeting.controller; package com.cmeeting.controller;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.azure.core.annotation.Post; import cn.hutool.json.JSONUtil;
import com.cmeeting.annotation.OperLog; import com.cmeeting.annotation.OperLog;
import com.cmeeting.constant.DeptCollect;
import com.cmeeting.pojo.SysUserSyncCategory; import com.cmeeting.pojo.SysUserSyncCategory;
import com.cmeeting.service.IUserAccessRecordService;
import com.cmeeting.service.MeetingInfoService; import com.cmeeting.service.MeetingInfoService;
import com.cmeeting.service.MeetingRecordTemplateService;
import com.cmeeting.service.SysUserSyncService; import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.R; import com.cmeeting.util.R;
import com.cmeeting.util.page.PageUtil; import com.cmeeting.util.page.PageUtil;
import com.sun.javafx.binding.StringFormatter; import com.cmeeting.vo.StatisticVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
...@@ -32,12 +34,15 @@ import java.util.stream.Collectors; ...@@ -32,12 +34,15 @@ import java.util.stream.Collectors;
**/ **/
@RestController @RestController
@RequestMapping("/statistics") @RequestMapping("/statistics")
@Slf4j
public class StatisticsController { public class StatisticsController {
@Autowired @Resource
private MeetingInfoService meetingInfoService; private MeetingInfoService meetingInfoService;
@Autowired @Resource
private SysUserSyncService sysUserSyncService; private SysUserSyncService sysUserSyncService;
@Resource
private IUserAccessRecordService iUserAccessRecordService;
/** /**
* 纪要模板使用情况的统计 * 纪要模板使用情况的统计
...@@ -56,9 +61,28 @@ public class StatisticsController { ...@@ -56,9 +61,28 @@ public class StatisticsController {
return PageUtil.getDataTable(list); return PageUtil.getDataTable(list);
} }
/**
* 纪要模板使用情况的统计
* @param searchValue 用户部门或工号
* @param createTimeStart 开始时间
* @param createTimeEnd 结束时间
* @return
*/
@OperLog(location = "统计日志", operation = "导出统计日志")
@GetMapping("/exportRecordTemplateUsingInfo")
public R exportRecordTemplateUsingInfo(String searchValue,
@RequestParam("createTimeStart") Date createTimeStart,
@RequestParam("createTimeEnd") Date createTimeEnd,
HttpServletResponse response) {
meetingInfoService.exportRecordTemplateUsingInfo(searchValue, createTimeStart, createTimeEnd, response);
return R.ok();
}
@PostMapping("/useInfoByCompany") @PostMapping("/useInfoByCompany")
public R useInfoByCompany(@Validated @RequestBody UseInfoByCompanyVO vo) throws ParseException { public R useInfoByCompany(@Validated @RequestBody StatisticVO vo) throws ParseException {
List<SysUserSyncCategory> tree = sysUserSyncService.getTree(); List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
String search = vo.getSearch(); String search = vo.getSearch();
if (StrUtil.isNotBlank(search)) { if (StrUtil.isNotBlank(search)) {
tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList()); tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
...@@ -73,9 +97,9 @@ public class StatisticsController { ...@@ -73,9 +97,9 @@ public class StatisticsController {
return PageUtil.getDataTable(list); return PageUtil.getDataTable(list);
} }
@PostMapping("/exportUseInfoByCompany") @PostMapping("/exportUseInfoByCompany")
public void exportUseInfoByCompany(@Validated @RequestBody UseInfoByCompanyVO vo, HttpServletResponse response) throws ParseException, IOException { public void exportUseInfoByCompany(@Validated @RequestBody StatisticVO vo, HttpServletResponse response) throws ParseException, IOException {
String search = vo.getSearch(); String search = vo.getSearch();
List<SysUserSyncCategory> tree = sysUserSyncService.getTree(); List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
if (StrUtil.isNotBlank(search)) { if (StrUtil.isNotBlank(search)) {
tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList()); tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
} }
...@@ -86,25 +110,49 @@ public class StatisticsController { ...@@ -86,25 +110,49 @@ public class StatisticsController {
String title = "会议纪要推送次数统计.docx"; String title = "会议纪要推送次数统计.docx";
meetingInfoService.statisticsEmail(title, simpleDateFormat1.parse(simpleDateFormat.format(vo.getStartTime()) + " 00:00:00"), meetingInfoService.statisticsEmail(title, simpleDateFormat1.parse(simpleDateFormat.format(vo.getStartTime()) + " 00:00:00"),
simpleDateFormat1.parse(simpleDateFormat.format(vo.getEndTime()) + " 23:59:59"), response.getOutputStream(), collect); simpleDateFormat1.parse(simpleDateFormat.format(vo.getEndTime()) + " 23:59:59"), response.getOutputStream(), collect);
} }
/** @PostMapping("/userAccessRecord")
* 纪要模板使用情况的统计 public R userAccessRecord(@Validated @RequestBody StatisticVO vo){
* @param searchValue 用户部门或工号 return R.ok(iUserAccessRecordService.statistics(vo.getSearch(), vo.getStartTime(), vo.getEndTime(), vo.getCurrent(), vo.getSize()));
* @param createTimeStart 开始时间 }
* @param createTimeEnd 结束时间 @PostMapping("/exportUserAccessRecord")
* @return public void exportUserAccessRecord(@Validated @RequestBody StatisticVO vo, HttpServletResponse response){
*/ List<Map<String, String>> statistics = iUserAccessRecordService.statistics(vo.getSearch(), vo.getStartTime(), vo.getEndTime(), vo.getCurrent(), vo.getSize());
@OperLog(location = "统计日志", operation = "导出统计日志") List<String> dateList = DateUtil.rangeToList(vo.getStartTime(), vo.getEndTime(), DateField.DAY_OF_YEAR).stream()
@GetMapping("/exportRecordTemplateUsingInfo") .map(date -> DateUtil.format(date, "yyyy-MM-dd"))
public R exportRecordTemplateUsingInfo(String searchValue, .collect(Collectors.toList());
@RequestParam("createTimeStart") Date createTimeStart, iUserAccessRecordService.exportUserAccessRecord(statistics, dateList, response);
@RequestParam("createTimeEnd") Date createTimeEnd, }
HttpServletResponse response) { @PostMapping("/userAccessRecordByCompany")
public R userAccessRecordByCompany(@Validated @RequestBody StatisticVO vo){
String search = vo.getSearch();
List<SysUserSyncCategory> treeList = sysUserSyncService.getTreeList();
if (StrUtil.isNotBlank(search)) {
treeList = treeList.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
}
List<String> collect = treeList.stream().map(SysUserSyncCategory::getPath).collect(Collectors.toList());
meetingInfoService.exportRecordTemplateUsingInfo(searchValue, createTimeStart, createTimeEnd, response); if (CollUtil.isEmpty(collect)) {
return R.ok(new ArrayList<>());
}
return R.ok(iUserAccessRecordService.statisticsByCompany(vo.getStartTime(), vo.getEndTime(), collect));
}
@PostMapping("/exportUserAccessRecordByCompany")
public void exportUserAccessRecordByCompany(@Validated @RequestBody StatisticVO vo, HttpServletResponse response) throws IOException {
String search = vo.getSearch();
List<SysUserSyncCategory> treeList = sysUserSyncService.getTreeList();
if (StrUtil.isNotBlank(search)) {
treeList = treeList.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
}
List<String> collect = treeList.stream().map(SysUserSyncCategory::getPath).collect(Collectors.toList());
return R.ok(); List<String> dateList = DateUtil.rangeToList(vo.getStartTime(), vo.getEndTime(), DateField.DAY_OF_YEAR).stream()
.map(date -> DateUtil.format(date, "yyyy-MM-dd"))
.collect(Collectors.toList());
List<Map<String, String>> data = iUserAccessRecordService.statisticsByCompany(vo.getStartTime(), vo.getEndTime(), collect);
iUserAccessRecordService.exportUserAccessRecordByCompany(data, dateList, response);
} }
} }
...@@ -34,12 +34,12 @@ public class SysUseSyncController { ...@@ -34,12 +34,12 @@ public class SysUseSyncController {
@GetMapping("/getTree") @GetMapping("/getTree")
public R getTree(){ public R getTree(){
return R.ok(iSysUserSyncService.getTree()); return R.ok(iSysUserSyncService.getTreeList());
} }
@GetMapping("/downloadTree") @GetMapping("/downloadTree")
public void downloadTree(HttpServletResponse response){ public void downloadTree(HttpServletResponse response){
iSysUserSyncService.downloadTree(iSysUserSyncService.getTree(), response); iSysUserSyncService.downloadTree(iSysUserSyncService.getTreeList(), response);
} }
} }
...@@ -322,7 +322,7 @@ public class CmeetingJob { ...@@ -322,7 +322,7 @@ public class CmeetingJob {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<SysUserSyncCategory> tree = sysUserSyncService.getTree(); List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
try { try {
boolean b = meetingInfoService.statisticsEmail(subject, simpleDateFormat1.parse(simpleDateFormat.format(date) + " 00:00:00"), boolean b = meetingInfoService.statisticsEmail(subject, simpleDateFormat1.parse(simpleDateFormat.format(date) + " 00:00:00"),
......
package com.cmeeting.mapper.primary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cmeeting.pojo.UserAccessRecord;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
public interface UserAccessRecordMapper extends BaseMapper<UserAccessRecord> {
@MapKey("userId")
Page<Map<String, String>> statisticsByDate(@Param("page") Page page, @Param("search") String search, @Param("startTime") String startTime,
@Param("endTime") String endTime, @Param("dateList") List<String> dateList);
}
package com.cmeeting.pojo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import lombok.experimental.Accessors;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user_access_record")
public class UserAccessRecord {
private String id;
private String userId;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
}
package com.cmeeting.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cmeeting.pojo.UserAccessRecord;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
public interface IUserAccessRecordService extends IService<UserAccessRecord> {
List<Map<String, String>> statistics(String search, Date startTime, Date endTime, Integer current, Integer size);
List<Map<String, String>> statisticsByCompany(Date startTime, Date endTime, List<String> deptMap);
void exportUserAccessRecord(List<Map<String, String>> statistics, List<String> dateList, HttpServletResponse response);
void exportUserAccessRecordByCompany(List<Map<String, String>> data, List<String> dateList, HttpServletResponse response) throws IOException;
}
...@@ -47,7 +47,7 @@ public interface SysUserSyncService extends IService<SysUserSync> { ...@@ -47,7 +47,7 @@ public interface SysUserSyncService extends IService<SysUserSync> {
List<SysUserSync> listByUserIds(List<String> userIdList, String search); List<SysUserSync> listByUserIds(List<String> userIdList, String search);
List<SysUserSyncCategory> getTree(); List<SysUserSyncCategory> getTreeList();
void downloadTree(List<SysUserSyncCategory> list, HttpServletResponse response); void downloadTree(List<SysUserSyncCategory> list, HttpServletResponse response);
} }
...@@ -267,7 +267,7 @@ public class SysUserSyncServiceImpl extends ServiceImpl<SysUserSyncMapper, SysUs ...@@ -267,7 +267,7 @@ public class SysUserSyncServiceImpl extends ServiceImpl<SysUserSyncMapper, SysUs
} }
@Override @Override
public List<SysUserSyncCategory> getTree() { public List<SysUserSyncCategory> getTreeList() {
int companyIndex = 2; int companyIndex = 2;
List<Tree<String>> list = iSysUserSyncCategoryService.tree(); List<Tree<String>> list = iSysUserSyncCategoryService.tree();
Tree<String> tree = list.get(0); Tree<String> tree = list.get(0);
......
package com.cmeeting.controller; package com.cmeeting.vo;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
...@@ -15,7 +15,7 @@ import java.util.Date; ...@@ -15,7 +15,7 @@ import java.util.Date;
@Data @Data
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class UseInfoByCompanyVO { public class StatisticVO {
private String search; private String search;
@NotNull @NotNull
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
...@@ -25,4 +25,6 @@ public class UseInfoByCompanyVO { ...@@ -25,4 +25,6 @@ public class UseInfoByCompanyVO {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime; private Date endTime;
private Integer current;
private Integer size;
} }
<?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.cmeeting.mapper.primary.UserAccessRecordMapper">
<select id="statisticsByDate" resultType="java.util.Map">
SELECT
c.user_id as userId,
s.name,
sc.dept_id as deptId,
<foreach collection="dateList" item="d" separator=",">
cast(MAX(CASE WHEN time = #{d} THEN c.cnt ELSE 0 END) as char) AS `${d}`
</foreach>
FROM (
SELECT
user_id,
date_format(create_time, '%Y-%m-%d') as time,
count(user_id) AS cnt
FROM
user_access_record
WHERE
date_format(create_time, '%Y-%m-%d') BETWEEN #{startTime} AND #{endTime}
GROUP BY user_id, date_format(create_time, '%Y-%m-%d')
) AS c
inner join sys_user_sync as s on s.user_id = c.user_id
<if test="search != null and search != ''">
and (s.name like concat('%',#{search},'%') or s.user_id like concat('%',#{search},'%'))
</if>
inner join sys_user_sync_category as sc on sc.dept_id = s.dept_id
GROUP BY c.user_id
</select>
</mapper>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论