Ver Fonte

7天在线时长统计

yzc há 1 ano atrás
pai
commit
3ee6cd8122

+ 31 - 0
hx-common/src/main/java/com/fjhx/common/controller/on/OnLineInfoController.java

@@ -0,0 +1,31 @@
+package com.fjhx.common.controller.on;
+
+import com.fjhx.common.entity.on.vo.OnLineInfoReturnData;
+import com.fjhx.common.service.on.OnLineInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 在线时长信息 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@RestController
+@RequestMapping("/onLineInfo")
+public class OnLineInfoController {
+
+    @Autowired
+    private OnLineInfoService onLineInfoService;
+
+    @GetMapping("/info")
+    OnLineInfoReturnData onLineInfo() {
+        return onLineInfoService.onLineInfo();
+    }
+
+}

+ 17 - 0
hx-common/src/main/java/com/fjhx/common/entity/on/dto/OnLineInfoDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.common.entity.on.dto;
+
+import com.fjhx.common.entity.on.po.OnLineInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 在线时长信息新增编辑入参实体
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@Getter
+@Setter
+public class OnLineInfoDto extends OnLineInfo {
+
+}

+ 17 - 0
hx-common/src/main/java/com/fjhx/common/entity/on/dto/OnLineInfoSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.common.entity.on.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 在线时长信息列表查询入参实体
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@Getter
+@Setter
+public class OnLineInfoSelectDto extends BaseSelectDto {
+
+}

+ 43 - 0
hx-common/src/main/java/com/fjhx/common/entity/on/po/OnLineInfo.java

@@ -0,0 +1,43 @@
+package com.fjhx.common.entity.on.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 在线时长信息
+ * </p>
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@Getter
+@Setter
+@TableName("on_line_info")
+public class OnLineInfo extends BasePo {
+
+    /**
+     * 用户id
+     */
+    private Long userId;
+
+    /**
+     * 每日在线时长(秒)
+     */
+    private Long onLineDuration;
+
+    /**
+     * 在线日期
+     */
+    private Date onLineDate;
+
+    /**
+     * 最后一次在线时间
+     */
+    private Date lastOnlineTime;
+
+}

+ 33 - 0
hx-common/src/main/java/com/fjhx/common/entity/on/vo/OnLineInfoReturnData.java

@@ -0,0 +1,33 @@
+package com.fjhx.common.entity.on.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Getter
+@Setter
+public
+class OnLineInfoReturnData {
+    private BigDecimal onLineTime;
+    private List<Dept> deptList;
+
+
+    @Getter
+    @Setter
+    public static class Dept {
+        private String deptName;
+        private BigDecimal onLineTime;
+        private List<User> userList;
+        private List<Dept> deptList;
+    }
+
+    @Getter
+    @Setter
+    public static class User {
+        private String userName;
+        private BigDecimal onLineTime;
+    }
+}
+

+ 27 - 0
hx-common/src/main/java/com/fjhx/common/entity/on/vo/OnLineInfoVo.java

@@ -0,0 +1,27 @@
+package com.fjhx.common.entity.on.vo;
+
+import com.fjhx.common.entity.on.po.OnLineInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 在线时长信息列表查询返回值实体
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@Getter
+@Setter
+public class OnLineInfoVo extends OnLineInfo {
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 用户名
+     */
+    private String userName;
+
+}

+ 27 - 0
hx-common/src/main/java/com/fjhx/common/mapper/on/OnLineInfoMapper.java

@@ -0,0 +1,27 @@
+package com.fjhx.common.mapper.on;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.common.entity.on.po.OnLineInfo;
+import com.fjhx.common.entity.on.vo.OnLineInfoVo;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 在线时长信息 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-08-08
+ */
+public interface OnLineInfoMapper extends BaseMapper<OnLineInfo> {
+
+    /**
+     * 获取7天内的在线时长
+     */
+    Long getOnLineTimeByUserId(Long userId);
+
+    List<OnLineInfoVo> getOnLineTimeByDeptIds(List<Long> deptIds);
+
+}

+ 19 - 0
hx-common/src/main/java/com/fjhx/common/service/on/OnLineInfoService.java

@@ -0,0 +1,19 @@
+package com.fjhx.common.service.on;
+
+import com.fjhx.common.entity.on.po.OnLineInfo;
+import com.fjhx.common.entity.on.vo.OnLineInfoReturnData;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 在线时长信息 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-08-08
+ */
+public interface OnLineInfoService extends BaseService<OnLineInfo> {
+
+    OnLineInfoReturnData onLineInfo();
+}

+ 163 - 0
hx-common/src/main/java/com/fjhx/common/service/on/impl/OnLineInfoServiceImpl.java

@@ -0,0 +1,163 @@
+package com.fjhx.common.service.on.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.entity.on.po.OnLineInfo;
+import com.fjhx.common.entity.on.vo.OnLineInfoReturnData;
+import com.fjhx.common.entity.on.vo.OnLineInfoVo;
+import com.fjhx.common.mapper.on.OnLineInfoMapper;
+import com.fjhx.common.service.on.OnLineInfoService;
+import com.fjhx.socket.core.WebSocketServer;
+import com.fjhx.socket.core.event.WebSocketOnMessageEvent;
+import com.fjhx.socket.core.event.WebSocketOnOpenEvent;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.system.service.ISysDeptService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * <p>
+ * 在线时长信息 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-08-08
+ */
+@Service
+public class OnLineInfoServiceImpl extends ServiceImpl<OnLineInfoMapper, OnLineInfo> implements OnLineInfoService {
+
+    @Autowired
+    private ISysDeptService sysDeptService;
+
+    @Override
+    public OnLineInfoReturnData onLineInfo() {
+        Long userId = SecurityUtils.getUserId();
+
+
+        //部门负责人:可查看负责部门/部门总监:可以查看对应部门及级联部门
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        List<SysDept> deptList = sysDeptService.list(Wrappers.<SysDept>lambdaQuery()
+                .eq(SysDept::getLeaderId, userId)
+                .or()
+                .eq(SysDept::getDirectorId, userId)
+        );
+        DynamicDataSourceContextHolder.poll();
+
+        //递归获取子数据
+        List<OnLineInfoReturnData.Dept> deptList1 = getDeptList(deptList, userId, 0);
+
+        //返回数据
+        OnLineInfoReturnData onLineInfoReturnData = new OnLineInfoReturnData();
+        //我的在线时长
+        BigDecimal divide = BigDecimal.valueOf(baseMapper.getOnLineTimeByUserId(userId)).divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP);
+        onLineInfoReturnData.setOnLineTime(divide);
+        //部门列表
+        onLineInfoReturnData.setDeptList(deptList1);
+
+        return onLineInfoReturnData;
+    }
+
+    List<OnLineInfoReturnData.Dept> getDeptList(List<SysDept> deptList, Long userId, Integer type) {
+        List<OnLineInfoReturnData.Dept> deptList1 = new ArrayList<>();
+        for (SysDept sysDept : deptList) {
+            List<OnLineInfoReturnData.User> userList = new ArrayList<>();
+            //获取用户列表
+            List<OnLineInfoVo> onLineTimeByDeptIds = baseMapper.getOnLineTimeByDeptIds(Collections.singletonList(sysDept.getDeptId()));
+            BigDecimal deptOnLineTime = BigDecimal.ZERO;
+            for (OnLineInfoVo onLineTimeByDeptId : onLineTimeByDeptIds) {
+                OnLineInfoReturnData.User user = new OnLineInfoReturnData.User();
+                user.setUserName(onLineTimeByDeptId.getUserName());
+
+                BigDecimal divide = BigDecimal.valueOf(onLineTimeByDeptId.getOnLineDuration()).divide(BigDecimal.valueOf(3600), 2, BigDecimal.ROUND_HALF_UP);
+                user.setOnLineTime(divide);
+                userList.add(user);
+
+                deptOnLineTime = deptOnLineTime.add(divide);
+            }
+
+            OnLineInfoReturnData.Dept dept1 = new OnLineInfoReturnData.Dept();
+            dept1.setDeptName(sysDept.getDeptName());
+            dept1.setUserList(userList);
+            dept1.setOnLineTime(deptOnLineTime);
+
+
+            //如果部门总监是我 查询部门下的子部门(type=1是递归进来的需要查子部门)
+            if (type == 1 || userId.equals(sysDept.getDirectorId())) {
+                DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+                List<SysDept> deptList11 = sysDeptService.list(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getParentId, sysDept.getDeptId()));
+                DynamicDataSourceContextHolder.poll();
+                dept1.setDeptList(getDeptList(deptList11, userId, 1));
+            }
+
+            //返回数据
+            deptList1.add(dept1);
+        }
+        return deptList1;
+    }
+
+    /**
+     * 用户连接websock监听
+     */
+    @EventListener
+    public void webSocketOnOpenEvent(WebSocketOnOpenEvent webSocketOnOpenEvent) {
+        WebSocketServer webSocketServer = webSocketOnOpenEvent.getWebSocketServer();
+        Long userId = webSocketServer.getUserId();
+        //记录上线时间
+        OnLineInfo onLineInfo = this.getOne(q -> q.eq(OnLineInfo::getUserId, userId).apply("DATE(on_line_date) = DATE(NOW())"));
+        if (ObjectUtil.isNotEmpty(onLineInfo)) {
+            onLineInfo = new OnLineInfo();
+            onLineInfo.setOnLineDuration(0L);
+            onLineInfo.setOnLineDate(new Date());
+        }
+        onLineInfo.setLastOnlineTime(new Date());
+        this.saveOrUpdate(onLineInfo);
+    }
+
+    /**
+     * 收到websock消息监听
+     */
+    @EventListener
+    public void webSocketOnMessageEvent(WebSocketOnMessageEvent webSocketOnMessageEvent) {
+        WebSocketServer webSocketServer = webSocketOnMessageEvent.getWebSocketServer();
+        Long userId = webSocketServer.getUserId();
+
+        String message = webSocketOnMessageEvent.getMessage();
+        JSONObject json = JSONObject.parseObject(message);
+        if (ObjectUtil.isNotEmpty(json.get("heartbeat"))) {
+            //保存在线时长信息
+            OnLineInfo onLineInfo = this.getOne(q -> q.eq(OnLineInfo::getUserId, userId).apply("DATE(on_line_date) = DATE(NOW())"));
+            if (ObjectUtil.isNotEmpty(onLineInfo)) {
+                onLineInfo = new OnLineInfo();
+                onLineInfo.setOnLineDuration(0L);
+                onLineInfo.setOnLineDate(new Date());
+            }
+
+
+            Long startTime = onLineInfo.getLastOnlineTime().getTime();
+            Date endDate = new Date();
+            //在线时长(秒)
+            long onLineTime = (endDate.getTime() - startTime) / 1000;
+
+            //记录在线时长
+            onLineInfo.setOnLineDuration(onLineInfo.getOnLineDuration() + onLineTime);
+            onLineInfo.setLastOnlineTime(endDate);
+            this.saveOrUpdate(onLineInfo);
+        }
+    }
+
+}
+
+

+ 33 - 0
hx-common/src/main/resources/mapper/on/OnLineInfoMapper.xml

@@ -0,0 +1,33 @@
+<?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.fjhx.common.mapper.on.OnLineInfoMapper">
+    <select id="getOnLineTimeByUserId" resultType="java.lang.Long">
+        SELECT IFNULL(sum(on_line_duration), 0)
+        FROM on_line_info
+        WHERE on_line_date >= NOW() - INTERVAL 7 DAY
+          AND user_id = #{userId}
+    </select>
+
+    <select id="getOnLineTimeByDeptIds" resultType="com.fjhx.common.entity.on.vo.OnLineInfoVo">
+        SELECT
+        oli.user_id,
+        IFNULL( sum( on_line_duration ), 0 ) on_line_duration,
+        dt.dept_id,
+        ur.nick_name userName
+        FROM
+        on_line_info oli
+        LEFT JOIN bytesailing_base.sys_user ur ON oli.user_id = ur.user_id
+        LEFT JOIN bytesailing_base.sys_dept dt ON dt.dept_id = ur.dept_id
+        <where>
+            on_line_date >= NOW() - INTERVAL 7 DAY
+            <if test="deptIds neq null and deptIds.size() > 0">
+                <foreach collection="deptIds" item="deptId" open="AND dt.dept_id IN (" separator="," close=")">
+                    #{deptId}
+                </foreach>
+            </if>
+        </where>
+        GROUP BY
+        oli.id
+    </select>
+
+</mapper>