更改了sql,测试接口
Change-Id: I412dc58fd46e5bd747cc870afdb1c0a5af09e06b
diff --git a/pom.xml b/pom.xml
index 65998ab..e26fb29 100644
--- a/pom.xml
+++ b/pom.xml
@@ -191,6 +191,12 @@
<artifactId>jackson-databind</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.github.pagehelper</groupId>
+ <artifactId>pagehelper-spring-boot-starter</artifactId>
+ <version>1.4.7</version>
+ </dependency>
+
</dependencies>
<build>
diff --git a/src/main/java/edu/bjtu/groupone/backend/api/WorkController.java b/src/main/java/edu/bjtu/groupone/backend/api/WorkController.java
index b181916..893bbb4 100644
--- a/src/main/java/edu/bjtu/groupone/backend/api/WorkController.java
+++ b/src/main/java/edu/bjtu/groupone/backend/api/WorkController.java
@@ -1,5 +1,6 @@
package edu.bjtu.groupone.backend.api;
+import com.github.pagehelper.PageInfo;
import edu.bjtu.groupone.backend.domain.dto.WorkResponse;
import edu.bjtu.groupone.backend.domain.dto.WorkDetailResponse;
import edu.bjtu.groupone.backend.domain.entity.Result;
@@ -38,7 +39,7 @@
@GetMapping
@Operation(summary = "获取作品列表", description = "可按分区分页查询作品")
- public ResponseEntity<Page<WorkResponse>> getWorks(
+ public ResponseEntity<PageInfo<WorkResponse>> getWorks(
@Parameter(description = "分区 ID(可选)") @RequestParam(required = false) Long categoryId,
@Parameter(description = "页码,从 1 开始", example = "1") @RequestParam(defaultValue = "1") int page,
@Parameter(description = "每页数量", example = "20") @RequestParam(defaultValue = "20") int size) {
@@ -74,7 +75,9 @@
@RequestParam("title") String title,
@RequestParam("author") String author,
@RequestParam("categoryId") Long categoryId,
- @RequestParam("description") String description) {
+ @RequestParam("description") String description,
+ @RequestParam("userId") Long userId,
+ @RequestParam("status") String status) {
try {
String coverUrl = aliOSSUtils.upload(cover);
Work work = new Work();
@@ -82,6 +85,8 @@
work.setAuthor(author);
work.setDescription(description);
work.setCover(coverUrl);
+ work.setUserId(userId);
+ work.setStatus(status);
Category category = new Category();
category.setId(categoryId);
work.setCategory(category);
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/dto/WorkDetailResponse.java b/src/main/java/edu/bjtu/groupone/backend/domain/dto/WorkDetailResponse.java
index 84065b0..f32d465 100644
--- a/src/main/java/edu/bjtu/groupone/backend/domain/dto/WorkDetailResponse.java
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/dto/WorkDetailResponse.java
@@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
+import java.util.Map;
@Data
public class WorkDetailResponse {
@@ -56,4 +57,5 @@
private String username;
private String uploadTotal;
}
+
}
\ No newline at end of file
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Version.java b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Version.java
index 1cd1706..b926b71 100644
--- a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Version.java
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Version.java
@@ -1,13 +1,16 @@
package edu.bjtu.groupone.backend.domain.entity;
+import jakarta.persistence.Column;
import lombok.Data;
@Data
public class Version {
private Long id;
+ @Column(name = "work_id", nullable = false)
private Long workId;
private String versionNumber;
private String fileUrl;
private String description; // 版本描述
private String createTime;
+
}
\ No newline at end of file
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Work.java b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Work.java
index 1549ce1..f1620f6 100644
--- a/src/main/java/edu/bjtu/groupone/backend/domain/entity/Work.java
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/entity/Work.java
@@ -1,3 +1,5 @@
+// edu.bjtu.groupone.backend.domain.entity.Work
+
package edu.bjtu.groupone.backend.domain.entity;
import jakarta.persistence.*;
@@ -5,15 +7,19 @@
@Entity
@Table(name = "works")
-@Data // 自动生成 getter/setter/toString
-@NoArgsConstructor // JPA 必需的无参构造
-@AllArgsConstructor // 全参构造
-@Builder // 关键修复:添加 Builder 模式
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
public class Work {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
+ /** 新增:用户 ID */
+ @Column(name = "user_id", nullable = false)
+ private Long userId;
+
@Column(nullable = false, length = 255)
private String title;
@@ -29,15 +35,21 @@
foreignKey = @ForeignKey(name = "fk_work_category")
)
private Category category;
+
@Column(columnDefinition = "TEXT")
private String description;
- @Column(name = "create_time")
+ /** 已有:创建时间 */
+ @Column(name = "create_time", updatable = false)
private String createTime;
+ /** 新增:更新时间 */
+ @Column(name = "update_time")
+ private String updateTime;
+
@Column(length = 255)
private String cover;
@Column(nullable = false, length = 20)
private String status;
-}
\ No newline at end of file
+}
diff --git a/src/main/java/edu/bjtu/groupone/backend/mapper/CommentMapper.java b/src/main/java/edu/bjtu/groupone/backend/mapper/CommentMapper.java
index e45ba4e..d8a69c9 100644
--- a/src/main/java/edu/bjtu/groupone/backend/mapper/CommentMapper.java
+++ b/src/main/java/edu/bjtu/groupone/backend/mapper/CommentMapper.java
@@ -10,13 +10,13 @@
@Insert("INSERT INTO `comment` (`post_id`, `user_id`, `content`, `create_time`) VALUES (#{postId}, #{userId}, #{content}, #{createTime})")
void insertComment(Comment comment);
- @Delete("DELETE FROM `comment` WHERE `comment_id` = #{commentId}")
+ @Delete("DELETE FROM `comment` WHERE `id` = #{commentId}")
void deleteComment(Long commentId);
@Update("UPDATE `comment` SET `post_id` = #{postId}, `user_id` = #{userId}, `content` = #{content}, `create_time` = #{createTime} WHERE `comment_id` = #{commentId}")
void updateComment(Comment comment);
- @Select("SELECT * FROM `comment` WHERE `comment_id` = #{commentId}")
+ @Select("SELECT * FROM `comment` WHERE `id` = #{commentId}")
Comment selectCommentById(Long commentId);
@Select("SELECT * FROM `comment` WHERE `post_id` = #{postId}")
diff --git a/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMapper.java b/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMapper.java
index ccf70c3..4ff8505 100644
--- a/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMapper.java
+++ b/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMapper.java
@@ -1,3 +1,5 @@
+// edu.bjtu.groupone.backend.mapper.WorkMapper
+
package edu.bjtu.groupone.backend.mapper;
import edu.bjtu.groupone.backend.domain.entity.Work;
@@ -11,25 +13,32 @@
@Mapper
public interface WorkMapper {
@Select("SELECT * FROM works WHERE user_id = #{userId} AND status = 'UPLOADING'")
- List<Work> getUncompletedWorksByUserId(Long userId);
+ List<Work> getUncompletedWorksByUserId(@Param("userId") Long userId);
@Select("SELECT * FROM works WHERE user_id = #{userId} AND status = 'COMPLETED'")
- List<Work> getCompletedWorksByUserId(Long userId);
+ List<Work> getCompletedWorksByUserId(@Param("userId") Long userId);
@Select("SELECT * FROM works WHERE id = #{id}")
- Work getWorkById(Long id);
+ Work getWorkById(@Param("id") Long id);
- @Insert("INSERT INTO works (title, description, user_id, status, create_time, update_time) " +
- "VALUES (#{title}, #{description}, #{userId}, #{status}, NOW(), NOW())")
+ @Insert("INSERT INTO works " +
+ "(title, description, user_id, status, category_id, create_time, update_time) " +
+ "VALUES " +
+ "(#{title}, #{description}, #{userId}, #{status}, #{category.id}, NOW(), NOW())")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertWork(Work work);
- @Update("UPDATE works SET title = #{title}, description = #{description}, status = #{status}, " +
- "update_time = NOW() WHERE id = #{id}")
+ @Update("UPDATE works SET " +
+ "title = #{title}, " +
+ "description = #{description}, " +
+ "status = #{status}, " +
+ "category_id = #{category.id}, " +
+ "update_time = NOW() " +
+ "WHERE id = #{id}")
int updateWork(Work work);
@Delete("DELETE FROM works WHERE id = #{id}")
- int deleteWork(Long id);
+ int deleteWork(@Param("id") Long id);
@Insert("INSERT INTO version (work_id, version_number, file_url, description, create_time) " +
"VALUES (#{workId}, #{versionNumber}, #{fileUrl}, #{description}, NOW())")
@@ -37,7 +46,7 @@
int insertVersion(Version version);
@Delete("DELETE FROM version WHERE id = #{id}")
- int deleteVersion(Long id);
+ int deleteVersion(@Param("id") Long id);
@Insert("INSERT INTO comment (work_id, user_id, content, create_time) " +
"VALUES (#{workId}, #{userId}, #{content}, NOW())")
@@ -45,18 +54,21 @@
int insertComment(Comment comment);
@Delete("DELETE FROM comment WHERE id = #{id}")
- int deleteComment(Long id);
+ int deleteComment(@Param("id") Long id);
- // 新增聚合查询
@Select("SELECT content FROM comment WHERE work_id = #{workId}")
- List<String> getCommentsByWorkId(Long workId);
+ List<String> getCommentsByWorkId(@Param("workId") Long workId);
@Select("SELECT version_number, file_url, description FROM version WHERE work_id = #{workId}")
- List<Map<String, Object>> getVersionsByWorkId(Long workId);
+ List<Map<String, Object>> getVersionsByWorkId(@Param("workId") Long workId);
- @Select("SELECT u.username, u.user_id FROM seeding_user su JOIN user u ON su.user_id = u.user_id WHERE su.work_id = #{workId} AND su.status = 'seeding'")
- List<Map<String, Object>> getSeedingUsersByWorkId(Long workId);
+ @Select("SELECT u.username, u.user_id FROM seeding_user su " +
+ "JOIN user u ON su.user_id = u.user_id " +
+ "WHERE su.work_id = #{workId} AND su.status = 'seeding'")
+ List<Map<String, Object>> getSeedingUsersByWorkId(@Param("workId") Long workId);
- @Select("SELECT u.username, u.user_id, su.uploaded FROM seeding_user su JOIN user u ON su.user_id = u.user_id WHERE su.work_id = #{workId} AND su.status = 'history'")
- List<Map<String, Object>> getHistorySeedingUsersByWorkId(Long workId);
-}
\ No newline at end of file
+ @Select("SELECT u.username, u.user_id, su.uploaded FROM seeding_user su " +
+ "JOIN user u ON su.user_id = u.user_id " +
+ "WHERE su.work_id = #{workId} AND su.status = 'history'")
+ List<Map<String, Object>> getHistorySeedingUsersByWorkId(@Param("workId") Long workId);
+}
diff --git a/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMybatisMapper.java b/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMybatisMapper.java
index c127c8c..58b5067 100644
--- a/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMybatisMapper.java
+++ b/src/main/java/edu/bjtu/groupone/backend/mapper/WorkMybatisMapper.java
@@ -2,6 +2,7 @@
package edu.bjtu.groupone.backend.mapper;
//import edu.bjtu.groupone.backend.model.Work;
+import edu.bjtu.groupone.backend.domain.dto.WorkResponse;
import edu.bjtu.groupone.backend.domain.entity.Work;
import org.apache.ibatis.annotations.*;
import org.springframework.data.domain.Page;
@@ -14,7 +15,19 @@
@Repository
public interface WorkMybatisMapper {
// 修正参数类型为 Spring Data 的 Pageable
- Page<Work> findByCategoryIdIn(List<Long> categoryIds, Pageable pageable);
+ @Select({
+ "<script>",
+ "SELECT *",
+ " FROM works",
+ " WHERE category_id IN",
+ " <foreach item='id' collection='categoryIds' open='(' separator=',' close=')'>",
+ " #{id}",
+ " </foreach>",
+ " ORDER BY create_time DESC",
+ "</script>"
+ })
+ List<WorkResponse> findByCategoryIdIn(List<Long> categoryIds);
+
@Insert("INSERT INTO works(title, author, views, category_id, description, create_time) " +
"VALUES(#{title}, #{author}, #{views}, #{category.id}, #{description}, #{createTime})")
@Options(useGeneratedKeys = true, keyProperty = "id")
diff --git a/src/main/java/edu/bjtu/groupone/backend/service/WorkService.java b/src/main/java/edu/bjtu/groupone/backend/service/WorkService.java
index 5693bb1..786193d 100644
--- a/src/main/java/edu/bjtu/groupone/backend/service/WorkService.java
+++ b/src/main/java/edu/bjtu/groupone/backend/service/WorkService.java
@@ -1,5 +1,7 @@
package edu.bjtu.groupone.backend.service;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
import edu.bjtu.groupone.backend.domain.dto.WorkResponse;
import edu.bjtu.groupone.backend.domain.entity.Work;
import edu.bjtu.groupone.backend.mapper.WorkMybatisMapper;
@@ -45,11 +47,13 @@
@Autowired
private CommentMapper commentMapper;
- public Page<WorkResponse> getWorks(Long categoryId, int page, int size) {
+ public PageInfo<WorkResponse> getWorks(Long categoryId, int page, int size) {
List<Long> categoryIds = categoryService.getAllSubcategoryIds(categoryId);
+ System.out.println("categoryIds = " + categoryIds);
Pageable pageable = PageRequest.of(page-1, size);
- return workMybatisMapper.findByCategoryIdIn(categoryIds, pageable)
- .map(this::convertToResponse);
+ PageHelper.startPage(page, size);
+ List<WorkResponse> byCategoryIdIn = workMybatisMapper.findByCategoryIdIn(categoryIds);
+ return new PageInfo<>(byCategoryIdIn);
}
private WorkResponse convertToResponse(Work work) {
diff --git a/src/main/resources/mapper/WorkMybatisMapper.xml b/src/main/resources/mapper/WorkMybatisMapper.xml
deleted file mode 100644
index dd0d444..0000000
--- a/src/main/resources/mapper/WorkMybatisMapper.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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="edu.bjtu.groupone.backend.mapper.WorkMybatisMapper">
-
- <!-- 结果集映射 -->
- <resultMap id="WorkResultMap" type="Work">
- <id property="id" column="id"/>
- <result property="title" column="title"/>
- <result property="description" column="description"/>
- <result property="categoryId" column="category_id"/>
- <result property="createTime" column="create_time"/>
- </resultMap>
-
- <!-- 查询所有作品 -->
- <select id="findAll" resultMap="WorkResultMap">
- SELECT id, title, description, category_id, create_time
- FROM works
- </select>
-
- <!-- 根据分类ID列表分页查询 -->
- <select id="findByCategoryIdIn" resultMap="WorkResultMap">
- SELECT * FROM works
- <where>
- <if test="categoryIds != null and categoryIds.size() > 0">
- category_id IN
- <foreach item="categoryId" collection="categoryIds"
- open="(" separator="," close=")">
- #{categoryId}
- </foreach>
- </if>
- </where>
- ORDER BY create_time DESC
- LIMIT #{pageable.pageSize} OFFSET #{pageable.offset}
- </select>
-
-</mapper>
\ No newline at end of file
diff --git a/src/test/java/edu/bjtu/groupone/backend/WorkServiceTest.java b/src/test/java/edu/bjtu/groupone/backend/WorkServiceTest.java
deleted file mode 100644
index 118ff01..0000000
--- a/src/test/java/edu/bjtu/groupone/backend/WorkServiceTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-package edu.bjtu.groupone.backend;
-
-import com.turn.ttorrent.tracker.Tracker;
-import edu.bjtu.groupone.backend.config.TrafficAwareTracker;
-import edu.bjtu.groupone.backend.domain.dto.WorkResponse;
-import edu.bjtu.groupone.backend.domain.entity.Category;
-import edu.bjtu.groupone.backend.domain.entity.Work;
-import edu.bjtu.groupone.backend.mapper.WorkMybatisMapper;
-import edu.bjtu.groupone.backend.mapper.WorkMapper;
-import edu.bjtu.groupone.backend.service.CategoryService;
-import edu.bjtu.groupone.backend.service.PeerTrafficService;
-import edu.bjtu.groupone.backend.service.WorkService;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.*;
-import static org.mockito.Mockito.*;
-
-@SpringBootTest
-@ExtendWith(MockitoExtension.class)
-class WorkServiceTest {
-
- @Mock
- private WorkMybatisMapper workMybatisMapper;
-
- @Mock
- private WorkMapper workMapper;
-
- @Mock
- private CategoryService categoryService;
-
- @InjectMocks
- private WorkService workService;
-
- private Work testWork;
- private Category testCategory;
- private List<Work> works;
-
- @BeforeEach
- void setUp() {
- testCategory = new Category(1L, "Test Category", null);
-
- testWork = Work.builder()
- .id(1L)
- .title("Test Work")
- .author("Author")
- .views(100)
- .category(testCategory)
- .build();
-
- Category category = new Category(1L, "文学艺术", null);
- works = Arrays.asList(
- Work.builder()
- .id(1L)
- .title("《我的世界》")
- .author("张三")
- .views(1234)
- .category(category)
- .description("一部关于...")
- .createTime("2023-06-15")
- .build(),
- Work.builder()
- .id(2L)
- .title("《你的世界》")
- .author("张三")
- .views(567)
- .category(category)
- .description("另一部关于...")
- .createTime("2023-06-16")
- .build()
- );
- }
-
- @Test
- void addWork_shouldCallMapper() {
- workService.addWork(testWork);
- verify(workMybatisMapper, times(1)).save(testWork);
- }
-
- @Test
- void createWork_shouldCallMapper() {
- workService.createWork(testWork);
- verify(workMapper, times(1)).insertWork(testWork);
- }
-
- @Test
- void deleteWork_shouldCallMapper() {
- workService.deleteWork(1L);
- verify(workMapper, times(1)).deleteWork(1L);
- }
-
- @Test
- void updateWork_shouldCallMapper() {
- workService.updateWork(testWork);
- verify(workMapper, times(1)).updateWork(testWork);
- }
-
- @Test
- void getWorkById_shouldReturnWork() {
- when(workMybatisMapper.findById(1L)).thenReturn(testWork);
- Work result = workService.getWorkById(1L);
- assertEquals(testWork, result);
- verify(workMybatisMapper, times(1)).findById(1L);
- }
-
- @Test
- void getWorks_shouldReturnPage() {
- Long categoryId = 1L;
- int page = 1; // Fix: Use page = 1 to account for WorkService expecting 1-based indexing
- int size = 10;
- List<Long> categoryIds = Arrays.asList(1L);
-
- when(categoryService.getAllSubcategoryIds(categoryId)).thenReturn(categoryIds);
- Page<Work> workPage = new PageImpl<>(Arrays.asList(testWork));
- when(workMybatisMapper.findByCategoryIdIn(categoryIds, PageRequest.of(0, size))).thenReturn(workPage);
-
- Page<WorkResponse> result = workService.getWorks(categoryId, page, size);
-
- assertEquals(1, result.getContent().size());
- verify(categoryService, times(1)).getAllSubcategoryIds(categoryId);
- verify(workMybatisMapper, times(1)).findByCategoryIdIn(categoryIds, PageRequest.of(0, size));
- }
-
- @Test
- void getWorksByAuthor_Success() {
- when(workMybatisMapper.findByAuthor("张三")).thenReturn(works);
- List<WorkResponse> result = workService.getWorksByAuthor("张三");
- assertEquals(2, result.size());
- assertEquals("《我的世界》", result.get(0).getTitle());
- assertEquals("《你的世界》", result.get(1).getTitle());
- }
-
- @Test
- void getWorksByAuthor_Empty() {
- when(workMybatisMapper.findByAuthor(anyString())).thenReturn(List.of());
- List<WorkResponse> result = workService.getWorksByAuthor("李四");
- assertTrue(result.isEmpty());
- }
-
- @Autowired
- PeerTrafficService peerTrafficService;
- @Test
- public void test() throws IOException {
- Tracker tracker;
- InetSocketAddress trackerAddress = new InetSocketAddress("0.0.0.0", 6969);
- tracker = new Tracker(trackerAddress);
- tracker.start();
- }
-}
\ No newline at end of file