Kaynağa Gözat

处理登录日志导出bug 演练报表完成率显示错误问题

jingyuanchao 1 yıl önce
ebeveyn
işleme
a5e6082fdf

+ 32 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/vo/LoginInfoStatusConverter.java

@@ -0,0 +1,32 @@
+package com.xunmei.system.api.vo;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+public class LoginInfoStatusConverter implements Converter<String> {
+
+
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return null;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return null;
+    }
+
+    @Override
+    public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return null;
+    }
+
+    @Override
+    public CellData convertToExcelData(String status, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return new CellData("1".equals(status)? "成功" : "失败");
+    }
+}

+ 32 - 0
soc-api/soc-api-system/src/main/java/com/xunmei/system/api/vo/PlafformTypeConverter.java

@@ -0,0 +1,32 @@
+package com.xunmei.system.api.vo;
+
+import com.alibaba.excel.converters.Converter;
+import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.GlobalConfiguration;
+import com.alibaba.excel.metadata.property.ExcelContentProperty;
+
+public class PlafformTypeConverter implements Converter<String> {
+
+
+
+    @Override
+    public Class supportJavaTypeKey() {
+        return null;
+    }
+
+    @Override
+    public CellDataTypeEnum supportExcelTypeKey() {
+        return null;
+    }
+
+    @Override
+    public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return null;
+    }
+
+    @Override
+    public CellData convertToExcelData(String platformType, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
+        return new CellData("0".equals(platformType)? "移动端" : "PC端");
+    }
+}

+ 8 - 12
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/drill/service/impl/CoreDrillPlanServiceImpl.java

@@ -21,7 +21,6 @@ import com.xunmei.common.core.domain.IdName;
 import com.xunmei.common.core.domain.compensate.dto.CompensateDto;
 import com.xunmei.common.core.domain.drill.domain.CoreDrillPlan;
 import com.xunmei.common.core.domain.drill.domain.CoreDrillPlanToExecOrg;
-import com.xunmei.common.core.domain.drill.domain.CoreDrillPlanToRole;
 import com.xunmei.common.core.domain.drill.domain.CoreDrillTask;
 import com.xunmei.common.core.domain.drill.dto.CoreDrillPlanInsertDto;
 import com.xunmei.common.core.domain.drill.dto.CoreDrillPlanPageDto;
@@ -30,8 +29,6 @@ import com.xunmei.common.core.domain.drill.vo.CoreDrillPlanDataVo;
 import com.xunmei.common.core.domain.drill.vo.CoreDrillPlanDetailVo;
 import com.xunmei.common.core.domain.drill.vo.CoreDrillPlanPageVo;
 import com.xunmei.common.core.domain.drill.vo.CoreDrillPlanRoleVo;
-import com.xunmei.common.core.domain.edu.domain.CoreEduTrainingPlan;
-import com.xunmei.common.core.domain.edu.domain.CoreEduTrainingPlanToExecOrg;
 import com.xunmei.common.core.domain.reminder.domain.CoreReminderSchedule;
 import com.xunmei.common.core.domain.reminder.vo.CoreReminderConfigurationFullVo;
 import com.xunmei.common.core.enums.BusinessPlanType;
@@ -42,7 +39,6 @@ import com.xunmei.common.core.enums.drill.DrillPlanCycleEnum;
 import com.xunmei.common.core.enums.drill.DrillPlanStatus;
 import com.xunmei.common.core.enums.edu.EduTrainingDoStatus;
 import com.xunmei.common.core.enums.edu.EduTrainingPlanCycleEnum;
-import com.xunmei.common.core.enums.edu.EduTrainingPlanStatus;
 import com.xunmei.common.core.exception.ServiceException;
 import com.xunmei.common.core.thread.ThreadPoolConfig;
 import com.xunmei.common.core.util.BeanHelper;
@@ -427,7 +423,7 @@ public class CoreDrillPlanServiceImpl extends ServiceImpl<CoreDrillPlanMapper, C
         List<Long> longs = baseMapper.selectAllIdByParentId(plan.getId());
         if (!longs.isEmpty()) {
             longs.remove(plan.getId());
-            if(!longs.isEmpty()){
+            if (!longs.isEmpty()) {
                 baseMapper.delByIds(longs);
             }
 //            physicalDeleteMapper.deletedDrillPlanByIds(longs);
@@ -961,38 +957,38 @@ public class CoreDrillPlanServiceImpl extends ServiceImpl<CoreDrillPlanMapper, C
                 }
                 compensateLogService.buildLog(getBusinessPlanType(), false, orgIdList, drillPlan.getId(), drillPlan.getPlanName(), errorMsg);
                 return;
-            }else{
+            } else {
                 Integer execOrgType = drillPlan.getExecOrgType();
                 List<Long> orgIds = coreDrillPlanToExecOrgMapper.selectOrgIdByPlanId(drillPlan.getId());
                 List<Long> ids = new ArrayList<>();
-                if(ObjectUtil.isNotEmpty(orgIds)){
+                if (ObjectUtil.isNotEmpty(orgIds)) {
                     //该计划是指定了具体机构的计划
                     //获取机构在 orgList子集机构
                     for (SysOrgVO sysOrgVO : orgList) {
                         List<SysOrg> sysOrgs = orgService.selectByOrgPathAndOrgType(sysOrgVO.getPath(), execOrgType, SecurityConstants.INNER);
-                        if(ObjectUtil.isNotEmpty(sysOrgs)){
+                        if (ObjectUtil.isNotEmpty(sysOrgs)) {
                             //获取sysOrgs 的属性id集合
                             List<Long> cids = sysOrgs.stream().map(SysOrg::getId).collect(toList());
                             //求cids和orgIds之间的交集
                             List<Long> collect = cids.stream().filter(id -> orgIds.contains(id)).collect(toList());
-                            if(!collect.isEmpty()){
+                            if (!collect.isEmpty()) {
                                 ids.addAll(collect);
                             }
                         }
                     }
-                }else{
+                } else {
                     //该计划是只指定了机构类型的计划
                     //获取orgList 机构树下的 机构类型
                     for (SysOrgVO sysOrgVO : orgList) {
                         List<SysOrg> sysOrgs = orgService.selectByOrgPathAndOrgType(sysOrgVO.getPath(), execOrgType, SecurityConstants.INNER);
-                        if(ObjectUtil.isNotEmpty(sysOrgs)){
+                        if (ObjectUtil.isNotEmpty(sysOrgs)) {
                             //获取sysOrgs 的属性id集合
                             ids.addAll(sysOrgs.stream().map(SysOrg::getId).collect(toList()));
                         }
                     }
                 }
                 create(drillPlan, ids);
-                compensateLogService.buildLog(getBusinessPlanType(), true, orgIdList, drillPlan.getId(), drillPlan.getPlanName(), errorMsg);
+                compensateLogService.buildLog(getBusinessPlanType(), false, orgIdList, drillPlan.getId(), drillPlan.getPlanName(), errorMsg);
                 return;
             }
         }

+ 17 - 9
soc-modules/soc-modules-core/src/main/java/com/xunmei/core/drill/service/impl/CoreDrillTaskServiceImpl.java

@@ -77,6 +77,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URLEncoder;
+import java.text.NumberFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -746,12 +747,20 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
             }
         }
         if (!SecurityUtils.isApp()) {
-            result.forEach(r -> r.setFinishRate(r.getFinishRate() + "%"));
+            result.forEach(r -> {
+                if (!r.getFinishRate().contains("%")) {
+                    r.setFinishRate(r.getFinishRate() + "%");
+                }
+            });
             return result;
         }
         List<CoreDrillTaskReportVo> reportVoList = result.stream().sorted(Comparator.comparing(vo -> Double.valueOf(vo.getFinishRate()))).collect(Collectors.toList());
         Collections.reverse(reportVoList);
-        reportVoList.forEach(r -> r.setFinishRate(r.getFinishRate() + "%"));
+        reportVoList.forEach(r -> {
+            if (!r.getFinishRate().contains("%")) {
+                r.setFinishRate(r.getFinishRate() + "%");
+            }
+        });
         return reportVoList;
     }
 
@@ -777,13 +786,12 @@ public class CoreDrillTaskServiceImpl extends ServiceImpl<CoreDrillTaskMapper, C
         }
         int shouldFinish = childrenOrgData.stream().map(CoreDrillTaskReportVo::getShouldFinish).reduce(Integer::sum).orElse(0);
         //计算完成率
-        BigDecimal finishBigDecimal = new BigDecimal(finish);
-        BigDecimal shouldFinishBigDecimal = new BigDecimal(shouldFinish);
-
-        BigDecimal divide = finishBigDecimal.divide(shouldFinishBigDecimal, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros();
-
-
-        return divide.toString();
+        BigDecimal a1 = new BigDecimal(finish);
+        BigDecimal a2 = new BigDecimal(shouldFinish);
+        BigDecimal r = a1.divide(a2, 4, RoundingMode.HALF_UP);
+        NumberFormat percent = NumberFormat.getPercentInstance();
+        percent.setMaximumFractionDigits(4);
+        return percent.format(r.doubleValue());
 
     }
 

+ 2 - 2
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/controller/SysLogininforController.java

@@ -15,7 +15,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
-import java.util.List;
 
 /**
  * 系统访问记录
@@ -42,7 +41,8 @@ public class SysLogininforController extends BaseController
     @PostMapping("/export")
     public void export(HttpServletResponse response, SysLogininfor logininfor)
     {
-        List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
+
+        logininforService.exportLoginInfo(logininfor,response);
     }
 
     @RequiresPermissions("system:logininfor:remove")

+ 3 - 1
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/service/ISysLogininforService.java

@@ -2,9 +2,9 @@ package com.xunmei.system.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.xunmei.common.core.web.page.TableDataInfo;
-import com.xunmei.system.api.domain.SysArea;
 import com.xunmei.system.api.domain.SysLogininfor;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 
 /**
@@ -48,4 +48,6 @@ public interface ISysLogininforService extends IService<SysLogininfor>
      * 清空系统登录日志
      */
     void cleanLogininfor();
+
+    void exportLoginInfo(SysLogininfor loginInfo, HttpServletResponse response);
 }

+ 44 - 6
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/service/impl/SysLogininforServiceImpl.java

@@ -1,20 +1,27 @@
 package com.xunmei.system.service.impl;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.xunmei.common.core.exception.SystemException;
+import com.xunmei.common.core.util.BeanHelper;
 import com.xunmei.common.core.utils.DateUtils;
 import com.xunmei.common.core.web.page.TableDataInfo;
-import com.xunmei.system.api.domain.SysArea;
-import com.xunmei.system.api.domain.SysDictData;
-import com.xunmei.system.api.domain.SysDictType;
 import com.xunmei.system.api.domain.SysLogininfor;
-import com.xunmei.system.mapper.SysDictTypeMapper;
 import com.xunmei.system.mapper.SysLogininforMapper;
 import com.xunmei.system.service.ISysLogininforService;
+import com.xunmei.system.vo.area.SysLoginInfoExportVo;
+import com.xunmei.system.vo.area.ValueCellWriteHandler;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -40,12 +47,13 @@ public class SysLogininforServiceImpl extends ServiceImpl<SysLogininforMapper, S
         QueryWrapper<SysLogininfor> where = new QueryWrapper<>(logininfor);
         Object beginTime = logininfor.getParams().get("beginTime");
         Object endTime = logininfor.getParams().get("endTime");
-        if(beginTime != null){
+        if (beginTime != null) {
             where.lambda().ge(SysLogininfor::getAccessTime, DateUtils.parseDate(beginTime));
         }
-        if(endTime != null){
+        if (endTime != null) {
             where.lambda().le(SysLogininfor::getAccessTime, DateUtils.parseDate(endTime));
         }
+        where.orderByDesc("access_time");
         baseMapper.selectPage(page, where);
         return TableDataInfo.build(page);
     }
@@ -89,4 +97,34 @@ public class SysLogininforServiceImpl extends ServiceImpl<SysLogininforMapper, S
     public void cleanLogininfor() {
         logininforMapper.cleanLogininfor();
     }
+
+    @Override
+    public void exportLoginInfo(SysLogininfor loginInfo, HttpServletResponse response) {
+        List<SysLogininfor> list = this.selectLogininforList(loginInfo);
+        if (ObjectUtil.isEmpty(list)) {
+            throw new SystemException("未获取到数据");
+        }
+        List<SysLoginInfoExportVo> dataList = BeanHelper.copyProperties(list, SysLoginInfoExportVo.class);
+
+        try {
+            String baseHeaderName = "登录日志表";
+            // 设置响应头
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(baseHeaderName, "utf-8"));
+            response.setContentType("application/octet-stream;charset=UTF-8");
+            response.setCharacterEncoding("utf-8");
+            String header = baseHeaderName + "(" + DateUtil.format(new Date(), "yyyy-MM") + "至" + DateUtil.format(new Date(), "yyyy-MM") + ")";
+
+            // 数据导出
+            EasyExcel.write(response.getOutputStream(), SysLoginInfoExportVo.class)
+                    .registerWriteHandler(new ValueCellWriteHandler(header))
+                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+                    .sheet(baseHeaderName)
+                    .doWrite(dataList);
+        } catch (Exception e) {
+            response.reset();
+            response.setContentType("application/json");
+            response.setCharacterEncoding("utf-8");
+        }
+
+    }
 }

+ 42 - 0
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/vo/area/SysLoginInfoExportVo.java

@@ -0,0 +1,42 @@
+package com.xunmei.system.vo.area;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.ContentRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.xunmei.system.api.vo.LoginInfoStatusConverter;
+import com.xunmei.system.api.vo.PlafformTypeConverter;
+import lombok.Data;
+
+import java.util.Date;
+@Data
+@ColumnWidth(15) //列宽,最大值为255
+@HeadRowHeight(16) //表头行高
+@ContentRowHeight(16) //数据行高
+public class SysLoginInfoExportVo {
+
+
+    @ExcelProperty(value = "访问编号")
+    private Long infoId;
+
+    @ExcelProperty(value = "用户名称")
+    private String userName;
+
+    @ExcelProperty(value = "地址")
+    private String ipaddr;
+
+
+    @ExcelProperty(value = "登录状态", converter = LoginInfoStatusConverter.class)
+    private String status;
+
+    @ExcelProperty(value = "平台类型", converter = PlafformTypeConverter.class)
+    private String platformType;
+
+    @ExcelProperty(value = "访问时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date accessTime;
+
+    @ExcelProperty(value = "描述")
+    private String msg;
+}

+ 55 - 0
soc-modules/soc-modules-system/src/main/java/com/xunmei/system/vo/area/ValueCellWriteHandler.java

@@ -0,0 +1,55 @@
+package com.xunmei.system.vo.area;
+
+import com.alibaba.excel.metadata.CellData;
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.handler.CellWriteHandler;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.springframework.util.PropertyPlaceholderHelper;
+
+import java.util.List;
+import java.util.Properties;
+
+
+public class ValueCellWriteHandler implements CellWriteHandler {
+    private String cellWritervalue;
+    PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${","}");
+
+    public ValueCellWriteHandler(String cellvalue) {
+        this.cellWritervalue = cellvalue;
+    }
+
+    @Override
+    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
+                                 Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) {
+        if (head != null) {
+            List<String> headNameList = head.getHeadNameList();
+            if (CollectionUtils.isNotEmpty(headNameList)) {
+                Properties properties = new Properties();
+                properties.setProperty("cellWriterValue", cellWritervalue);
+                for (int i = 0; i < headNameList.size(); i++) {
+                    headNameList.set(i, propertyPlaceholderHelper.replacePlaceholders(headNameList.get(i), properties));
+                }
+            }
+        }
+    }
+
+    @Override
+    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) {
+
+    }
+
+    @Override
+    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {
+
+    }
+
+    @Override
+    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
+
+    }
+
+}

+ 3 - 2
soc-modules/soc-modules-system/src/main/resources/mapper/system/SysLogininforMapper.xml

@@ -11,6 +11,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="ipaddr"        column="ipaddr"            />
 		<result property="msg"           column="msg"               />
 		<result property="accessTime"    column="access_time"       />
+		<result property="platformType"    column="platform_type"       />
 	</resultMap>
 
 	<insert id="insertLogininfor" parameterType="com.xunmei.system.api.domain.SysLogininfor">
@@ -19,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	</insert>
 
 	<select id="selectLogininforList" parameterType="com.xunmei.system.api.domain.SysLogininfor" resultMap="SysLogininforResult">
-		select info_id, user_name, ipaddr, status, msg, access_time from sys_logininfor
+		select info_id, user_name, ipaddr, platform_type,status, msg, access_time from sys_logininfor
 		<where>
 			<if test="ipaddr != null and ipaddr != ''">
 				AND ipaddr like concat('%', #{ipaddr}, '%')
@@ -37,7 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 				AND access_time &lt;= #{params.endTime}
 			</if>
 		</where>
-		order by info_id desc
+		order by access_time desc
 	</select>
 
 	<delete id="deleteLogininforByIds" parameterType="Long">