【方案设计】针对监控服务-功能时长统计的几个实现方案
实现前后端针对用户功能时长的使用,可以从记录用户操作开始,到存储和展示功能使用时长。以下是几个实现方案的简单介绍:
方案一:基于时间戳记录
这种方案通过记录用户开始和结束使用功能的时间戳,然后在后端计算时长并存储,前端从后端获取数据进行展示。
前端实现
记录开始时间:在用户进入功能页面时,使用 Date.now() 获取当前时间戳并存储在本地变量中。
javascript
代码解读
复制代码
// 在进入功能页面时 let startTime = Date.now();
记录结束时间:在用户离开功能页面或完成操作时,再次获取当前时间戳。
javascript
代码解读
复制代码
// 在离开功能页面时 let endTime = Date.now();
发送时长数据到后端:将计算出的时长(endTime - startTime)发送到后端服务器。可以使用 fetch 或 axios 等库进行 HTTP 请求。
javascript
代码解读
复制代码
import axios from 'axios'; let duration = endTime - startTime; axios.post('/api/function-usage', { functionName: '特定功能名称', duration: duration }).then(response => { console.log('时长数据发送成功'); }).catch(error => { console.log('发送时长数据失败', error); });
后端实现(以 Spring Boot 为例)
接收前端数据:创建一个控制器来接收前端发送的时长数据。
java
代码解读
复制代码
@RestController @RequestMapping("/api") public class FunctionUsageController { @Autowired private FunctionUsageService functionUsageService; @PostMapping("/function-usage") public ResponseEntity
存储数据:创建一个服务类和对应的实体类来处理数据存储。
java
代码解读
复制代码
@Service public class FunctionUsageService { @Autowired private FunctionUsageRepository functionUsageRepository; public void saveFunctionUsage(FunctionUsage functionUsage) { functionUsageRepository.save(functionUsage); } }
java
代码解读
复制代码
@Entity @Table(name = "function_usage") public class FunctionUsage { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String functionName; private Long duration; // 可以添加用户标识字段,如 userId private Long userId; // 构造函数、getter 和 setter public FunctionUsage() {} public FunctionUsage(String functionName, Long duration, Long userId) { this.functionName = functionName; this.duration = duration; this.userId = userId; } // getters 和 setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFunctionName() { return functionName; } public void setFunctionName(String functionName) { this.functionName = functionName; } public Long getDuration() { return duration; } public void setDuration(Long duration) { this.duration = duration; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } }
java
代码解读
复制代码
@Repository public interface FunctionUsageRepository extends JpaRepository
方案二:使用 WebSocket 实时记录
这种方案通过 WebSocket 实时传输用户操作状态,后端可以更精确地记录功能使用时长。
前端实现
连接 WebSocket:使用 WebSocket API 连接到后端服务器。
javascript
代码解读
复制代码
let socket = new WebSocket('ws://localhost:8080/function-usage'); socket.onopen = function (event) { console.log('WebSocket 连接成功'); // 发送用户进入功能的消息 socket.send(JSON.stringify({ action: 'enter', functionName: '特定功能名称', userId: 1 // 假设用户 ID })); }; socket.onclose = function (event) { console.log('WebSocket 连接关闭'); // 发送用户离开功能的消息 socket.send(JSON.stringify({ action: 'leave', functionName: '特定功能名称', userId: 1 })); };
后端实现(以 Spring Boot + Spring WebSocket 为例)
配置 WebSocket:在 Spring Boot 中配置 WebSocket。
java
代码解读
复制代码
@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(functionUsageHandler(), "/function-usage").withSockJS(); } @Bean public WebSocketHandler functionUsageHandler() { return new FunctionUsageHandler(); } }
处理 WebSocket 消息:创建一个 WebSocketHandler 来处理前端发送的消息。
java
代码解读
复制代码
@Component public class FunctionUsageHandler extends TextWebSocketHandler { private final Map
java
代码解读
复制代码
public class FunctionUsageMessage { private String action; private String functionName; private Long userId; // 构造函数、getter 和 setter public FunctionUsageMessage() {} public FunctionUsageMessage(String action, String functionName, Long userId) { this.action = action; this.functionName = functionName; this.userId = userId; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getFunctionName() { return functionName; } public void setFunctionName(String functionName) { this.functionName = functionName; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } }
方案三:前端定时上报
前端定时向后端发送用户是否正在使用功能的状态,后端根据这些状态记录时长。
前端实现
定时发送状态:使用 setInterval 定时发送用户状态。
javascript
代码解读
复制代码
let isUsingFunction = true; // 假设用户正在使用功能 let intervalId = setInterval(() => { axios.post('/api/function-status', { functionName: '特定功能名称', isUsing: isUsingFunction, userId: 1 }).then(response => { console.log('状态数据发送成功'); }).catch(error => { console.log('发送状态数据失败', error); }); }, 60 * 1000); // 每分钟发送一次
后端实现
接收状态数据:创建控制器接收前端发送的状态数据。
java
代码解读
复制代码
@RestController @RequestMapping("/api") public class FunctionStatusController { @Autowired private FunctionUsageService functionUsageService; @PostMapping("/function-status") public ResponseEntity
处理状态数据并计算时长:在服务类中根据状态数据计算时长。
java
代码解读
复制代码
@Service public class FunctionUsageService { private final Map
java
代码解读
复制代码
public class FunctionStatus { private String functionName; private boolean isUsing; private Long userId; private Long lastUpdateTime; // 构造函数、getter 和 setter public FunctionStatus() { this.lastUpdateTime = System.currentTimeMillis(); } public FunctionStatus(String functionName, boolean isUsing, Long userId) { this.functionName = functionName; this.isUsing = isUsing; this.userId = userId; this.lastUpdateTime = System.currentTimeMillis(); } public String getFunctionName() { return functionName; } public void setFunctionName(String functionName) { this.functionName = functionName; } public boolean isUsing() { return isUsing; } public void setIsUsing(boolean isUsing) { this.isUsing = isUsing; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public Long getLastUpdateTime() { return lastUpdateTime; } public void setLastUpdateTime(Long lastUpdateTime) { this.lastUpdateTime = lastUpdateTime; } }
以上方案可以根据项目的具体需求和技术栈进行选择和调整,实现对用户功能时长的有效记录和使用。