提交 80e40c16 作者: 洪东保

用户登录统计及导出

父级 82f6e4d5
......@@ -88,11 +88,11 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
.authorizeRequests()
// 对于登录login 图标 要允许匿名访问
// .antMatchers(customApi).access("@robotJwtCustomTokenFilter.checkToken(request)")
.antMatchers("/agent/auth/**").anonymous()
.antMatchers(HttpMethod.GET, "/*.html", "/**/*.html", "/**/*.css",
"/**/*.js", "/**/*.map")
.permitAll()
.antMatchers("/error").anonymous()
.antMatchers("/agent/auth/**").anonymous()
.antMatchers("/user/login").anonymous()
.antMatchers("/user/userAuth").anonymous()
.antMatchers("/user/tokenAuth").anonymous()
......
......@@ -59,12 +59,12 @@ public class RobotJwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// 检查请求路径是否在白名单中
String requestURI = request.getRequestURI();
if (isWhiteListPath(requestURI)) {
chain.doFilter(request, response); // 放行,不验证JWT
return;
}
// // 检查请求路径是否在白名单中
// String requestURI = request.getRequestURI();
// if (isWhiteListPath(requestURI)) {
// chain.doFilter(request, response); // 放行,不验证JWT
// return;
// }
String token = jwtUtil.getToken(request);
if (StringUtils.isNotBlank(token)) {
......
......@@ -15,6 +15,8 @@ import com.cmeeting.exception.RobotBaseException;
import com.cmeeting.mapper.primary.AuthMapper;
import com.cmeeting.mapper.primary.SysUserSyncMapper;
import com.cmeeting.pojo.CoreModulePermissions;
import com.cmeeting.pojo.UserAccessRecord;
import com.cmeeting.service.IUserAccessRecordService;
import com.cmeeting.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
......@@ -31,10 +33,7 @@ import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
@Service
......@@ -69,6 +68,8 @@ public class UserServiceImpl implements UserService {
private AuthMapper authMapper;
@Resource
private SysUserSyncMapper sysUserSyncMapper;
@Resource
private IUserAccessRecordService iUserAccessRecordService;
@Override
public R login(String agentId, String data, String ip) {
......@@ -93,6 +94,8 @@ public class UserServiceImpl implements UserService {
String token = jwtUtil.generateToken(userDetail);
redisUtils.set(token, userDetail, Long.parseLong(expireTime));
// 记录登录日志
iUserAccessRecordService.save(UserAccessRecord.builder().userId(userId).createTime(new Date()).build());
return token;
}
......
......@@ -78,9 +78,6 @@ public class JwtUtil {
*/
public String getToken(HttpServletRequest request) {
String token = request.getHeader(tokenHeader);
if (StrUtil.isBlank(token)) {
throw new RobotBaseException("认证已过期!", 401);
}
if (StrUtil.isNotBlank(token) && token.length() > authTokenStart.length()) {
token = token.substring(authTokenStart.length()).trim();
}
......
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 com.azure.core.annotation.Post;
import cn.hutool.json.JSONUtil;
import com.cmeeting.annotation.OperLog;
import com.cmeeting.constant.DeptCollect;
import com.cmeeting.pojo.SysUserSyncCategory;
import com.cmeeting.service.IUserAccessRecordService;
import com.cmeeting.service.MeetingInfoService;
import com.cmeeting.service.MeetingRecordTemplateService;
import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.R;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -32,12 +34,15 @@ import java.util.stream.Collectors;
**/
@RestController
@RequestMapping("/statistics")
@Slf4j
public class StatisticsController {
@Autowired
@Resource
private MeetingInfoService meetingInfoService;
@Autowired
@Resource
private SysUserSyncService sysUserSyncService;
@Resource
private IUserAccessRecordService iUserAccessRecordService;
/**
* 纪要模板使用情况的统计
......@@ -56,9 +61,28 @@ public class StatisticsController {
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")
public R useInfoByCompany(@Validated @RequestBody UseInfoByCompanyVO vo) throws ParseException {
List<SysUserSyncCategory> tree = sysUserSyncService.getTree();
public R useInfoByCompany(@Validated @RequestBody StatisticVO vo) throws ParseException {
List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
String search = vo.getSearch();
if (StrUtil.isNotBlank(search)) {
tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
......@@ -73,9 +97,9 @@ public class StatisticsController {
return PageUtil.getDataTable(list);
}
@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();
List<SysUserSyncCategory> tree = sysUserSyncService.getTree();
List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
if (StrUtil.isNotBlank(search)) {
tree = tree.stream().filter(e -> search.equals(e.getDeptId()) || e.getPath().contains(search)).collect(Collectors.toList());
}
......@@ -86,25 +110,49 @@ public class StatisticsController {
String title = "会议纪要推送次数统计.docx";
meetingInfoService.statisticsEmail(title, simpleDateFormat1.parse(simpleDateFormat.format(vo.getStartTime()) + " 00:00:00"),
simpleDateFormat1.parse(simpleDateFormat.format(vo.getEndTime()) + " 23:59:59"), response.getOutputStream(), collect);
}
/**
* 纪要模板使用情况的统计
* @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) {
@PostMapping("/userAccessRecord")
public R userAccessRecord(@Validated @RequestBody StatisticVO vo){
return R.ok(iUserAccessRecordService.statistics(vo.getSearch(), vo.getStartTime(), vo.getEndTime(), vo.getCurrent(), vo.getSize()));
}
@PostMapping("/exportUserAccessRecord")
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());
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());
iUserAccessRecordService.exportUserAccessRecord(statistics, dateList, 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 {
@GetMapping("/getTree")
public R getTree(){
return R.ok(iSysUserSyncService.getTree());
return R.ok(iSysUserSyncService.getTreeList());
}
@GetMapping("/downloadTree")
public void downloadTree(HttpServletResponse response){
iSysUserSyncService.downloadTree(iSysUserSyncService.getTree(), response);
iSysUserSyncService.downloadTree(iSysUserSyncService.getTreeList(), response);
}
}
......@@ -322,7 +322,7 @@ public class CmeetingJob {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<SysUserSyncCategory> tree = sysUserSyncService.getTree();
List<SysUserSyncCategory> tree = sysUserSyncService.getTreeList();
try {
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> {
List<SysUserSync> listByUserIds(List<String> userIdList, String search);
List<SysUserSyncCategory> getTree();
List<SysUserSyncCategory> getTreeList();
void downloadTree(List<SysUserSyncCategory> list, HttpServletResponse response);
}
......@@ -267,7 +267,7 @@ public class SysUserSyncServiceImpl extends ServiceImpl<SysUserSyncMapper, SysUs
}
@Override
public List<SysUserSyncCategory> getTree() {
public List<SysUserSyncCategory> getTreeList() {
int companyIndex = 2;
List<Tree<String>> list = iSysUserSyncCategoryService.tree();
Tree<String> tree = list.get(0);
......
package com.cmeeting.controller;
package com.cmeeting.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
......@@ -15,7 +15,7 @@ import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UseInfoByCompanyVO {
public class StatisticVO {
private String search;
@NotNull
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
......@@ -25,4 +25,6 @@ public class UseInfoByCompanyVO {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论