统计用户当月上传量下载量功能
Change-Id: I2b5b29d3b8f34e2071f15d66fed6759997b063d4
diff --git a/src/main/java/com/pt5/pthouduan/controller/TrafficController.java b/src/main/java/com/pt5/pthouduan/controller/TrafficController.java
new file mode 100644
index 0000000..c07bd91
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/controller/TrafficController.java
@@ -0,0 +1,41 @@
+package com.pt5.pthouduan.controller;
+
+import com.pt5.pthouduan.entity.UserTrafficStat;
+import com.pt5.pthouduan.mapper.UserTrafficMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@RestController
+@RequestMapping("/api/traffic")
+public class TrafficController {
+
+ @Autowired
+ private UserTrafficMapper userTrafficMapper;
+
+ /**
+ * 获取指定用户在指定时间范围内的上传和下载量统计
+ * @param passkey 用户唯一标识(passkey)
+ * @param startDate 开始时间(格式:yyyy-MM-dd)
+ * @param endDate 结束时间(格式:yyyy-MM-dd)
+ * @return 该用户的上传和下载量统计
+ */
+ @GetMapping("/user-stats")
+ public ResponseEntity<UserTrafficStat> getUserTrafficStats(
+ @RequestParam String passkey, // 必须传入 passkey
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
+ @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
+
+ // 调用 Mapper 查询数据
+ UserTrafficStat stats = userTrafficMapper.getUserTrafficStats(passkey, startDate, endDate);
+
+ return ResponseEntity.ok(stats);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/pt5/pthouduan/entity/UserTrafficStat.java b/src/main/java/com/pt5/pthouduan/entity/UserTrafficStat.java
new file mode 100644
index 0000000..885d6af
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/entity/UserTrafficStat.java
@@ -0,0 +1,37 @@
+package com.pt5.pthouduan.entity;
+
+public class UserTrafficStat {
+ private String month; // 月份(YYYY-MM)
+ private Long totalUploaded; // 总上传量
+ private Long totalDownloaded; // 总下载量
+
+ // Getters & Setters
+ public String getMonth()
+ {
+ return month;
+ }
+ public void setMonth(String month)
+ {
+ this.month = month;
+ }
+ public Long getTotalUploaded()
+ {
+ return totalUploaded;
+ }
+ public void setTotalUploaded(Long totalUploaded)
+ {
+ this.totalUploaded = totalUploaded;
+ }
+ public Long getTotalDownloaded()
+ {
+ return totalDownloaded;
+ }
+ public void setTotalDownloaded(Long totalDownloaded)
+ {
+ this.totalDownloaded = totalDownloaded;
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/pt5/pthouduan/mapper/UserTrafficMapper.java b/src/main/java/com/pt5/pthouduan/mapper/UserTrafficMapper.java
new file mode 100644
index 0000000..2f82cb9
--- /dev/null
+++ b/src/main/java/com/pt5/pthouduan/mapper/UserTrafficMapper.java
@@ -0,0 +1,23 @@
+package com.pt5.pthouduan.mapper;
+
+import com.pt5.pthouduan.entity.UserTrafficStat;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Mapper
+public interface UserTrafficMapper {
+ /**
+ * 查询指定用户在指定时间范围内的上传和下载量(按月统计)
+ * @param passkey 用户唯一标识
+ * @param startDate 开始时间
+ * @param endDate 结束时间
+ * @return 该用户的月度统计
+ */
+ UserTrafficStat getUserTrafficStats(
+ @Param("passkey") String passkey,
+ @Param("startDate") LocalDate startDate,
+ @Param("endDate") LocalDate endDate);
+}
\ No newline at end of file
diff --git a/src/test/java/com/pt5/pthouduan/ControllerTest/TrafficControllerTest.java b/src/test/java/com/pt5/pthouduan/ControllerTest/TrafficControllerTest.java
new file mode 100644
index 0000000..81bbe7e
--- /dev/null
+++ b/src/test/java/com/pt5/pthouduan/ControllerTest/TrafficControllerTest.java
@@ -0,0 +1,84 @@
+package com.pt5.pthouduan.ControllerTest;
+
+
+import com.pt5.pthouduan.controller.TrafficController;
+import com.pt5.pthouduan.entity.UserTrafficStat;
+import com.pt5.pthouduan.mapper.UserTrafficMapper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+
+import java.time.LocalDate;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+class TrafficControllerTest {
+
+ private MockMvc mockMvc;
+
+ @Mock
+ private UserTrafficMapper userTrafficMapper; // 模拟 Mapper
+
+ @InjectMocks
+ private TrafficController trafficController; // 注入 Controller
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this); // 初始化 Mock
+ mockMvc = MockMvcBuilders.standaloneSetup(trafficController).build(); // 构建 MockMvc
+ }
+
+ @Test
+ void getUserTrafficStats_shouldReturnStats_whenPasskeyAndDatesAreValid() throws Exception {
+ // 准备测试数据
+ String passkey = "test-passkey";
+ LocalDate startDate = LocalDate.of(2023, 1, 1);
+ LocalDate endDate = LocalDate.of(2023, 1, 31);
+
+ UserTrafficStat mockStats = new UserTrafficStat();
+ mockStats.setTotalUploaded(1024L);
+ mockStats.setTotalDownloaded(2048L);
+
+ // 模拟 Mapper 行为
+ when(userTrafficMapper.getUserTrafficStats(anyString(), any(LocalDate.class), any(LocalDate.class)))
+ .thenReturn(mockStats);
+
+ // 发起 GET 请求并验证响应
+ mockMvc.perform(get("/api/traffic/user-stats")
+ .param("passkey", passkey)
+ .param("startDate", startDate.toString())
+ .param("endDate", endDate.toString())
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk()); // 预期 HTTP 200
+ }
+
+ @Test
+ void getUserTrafficStats_shouldReturn400_whenPasskeyIsMissing() throws Exception {
+ // 不传 passkey,预期返回 400 Bad Request
+ mockMvc.perform(get("/api/traffic/user-stats")
+ .param("startDate", "2023-01-01")
+ .param("endDate", "2023-01-31")
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ void getUserTrafficStats_shouldReturn400_whenDatesAreInvalid() throws Exception {
+ // 传入无效日期格式,预期返回 400 Bad Request
+ mockMvc.perform(get("/api/traffic/user-stats")
+ .param("passkey", "test-passkey")
+ .param("startDate", "2023-01-01-invalid")
+ .param("endDate", "2023-01-31")
+ .contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest());
+ }
+}
\ No newline at end of file