diff --git a/vocata-server/src/main/java/com/vocata/character/controller/CharacterOpenController.java b/vocata-server/src/main/java/com/vocata/character/controller/CharacterOpenController.java index 1cd5843..a7c96f7 100644 --- a/vocata-server/src/main/java/com/vocata/character/controller/CharacterOpenController.java +++ b/vocata-server/src/main/java/com/vocata/character/controller/CharacterOpenController.java @@ -13,6 +13,7 @@ import com.vocata.common.result.ApiResponse; import com.vocata.common.result.PageResult; import com.vocata.user.service.UserFavoriteService; +import org.postgresql.util.PGobject; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -197,13 +198,13 @@ private CharacterResponse convertMapToResponse(Map characterMap) // 复制角色基本信息,处理null值 response.setId(characterMap.get("id") != null ? Long.valueOf(characterMap.get("id").toString()) : null); - response.setCharacterCode((String) characterMap.get("character_code")); - response.setName((String) characterMap.get("name")); - response.setDescription((String) characterMap.get("description")); - response.setGreeting((String) characterMap.get("greeting")); - response.setAvatarUrl((String) characterMap.get("avatar_url")); - response.setTags((String) characterMap.get("tags")); - response.setLanguage((String) characterMap.get("language")); + response.setCharacterCode(toStringValue(characterMap.get("character_code"))); + response.setName(toStringValue(characterMap.get("name"))); + response.setDescription(toStringValue(characterMap.get("description"))); + response.setGreeting(toStringValue(characterMap.get("greeting"))); + response.setAvatarUrl(toStringValue(characterMap.get("avatar_url"))); + response.setTags(toStringValue(characterMap.get("tags"))); + response.setLanguage(toStringValue(characterMap.get("language"))); Integer status = (Integer) characterMap.get("status"); response.setStatus(status); @@ -239,11 +240,21 @@ private CharacterResponse convertMapToResponse(Map characterMap) } // 设置创建者名称 - response.setCreatorName((String) characterMap.get("creator_name")); + response.setCreatorName(toStringValue(characterMap.get("creator_name"))); return response; } + private String toStringValue(Object value) { + if (value == null) { + return null; + } + if (value instanceof PGobject pgObject) { + return pgObject.getValue(); + } + return value.toString(); + } + /** * 将Character实体转换为CharacterDetailResponse */ @@ -255,4 +266,4 @@ private CharacterDetailResponse convertToDetailResponse(Character character) { response.setUpdatedAt(character.getUpdateDate()); return response; } -} \ No newline at end of file +} diff --git a/vocata-server/src/test/java/com/vocata/character/controller/CharacterOpenControllerTest.java b/vocata-server/src/test/java/com/vocata/character/controller/CharacterOpenControllerTest.java new file mode 100644 index 0000000..85760b9 --- /dev/null +++ b/vocata-server/src/test/java/com/vocata/character/controller/CharacterOpenControllerTest.java @@ -0,0 +1,73 @@ +package com.vocata.character.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.vocata.character.dto.request.CharacterSearchRequest; +import com.vocata.character.dto.response.CharacterResponse; +import com.vocata.character.service.CharacterService; +import com.vocata.common.result.ApiResponse; +import com.vocata.common.result.PageResult; +import org.junit.jupiter.api.Test; +import org.postgresql.util.PGobject; +import org.springframework.test.util.ReflectionTestUtils; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class CharacterOpenControllerTest { + + @Test + void publicCharacterListConvertsPostgresJsonObjectsToStrings() throws Exception { + CharacterService characterService = mock(CharacterService.class); + CharacterOpenController controller = new CharacterOpenController(); + ReflectionTestUtils.setField(controller, "characterService", characterService); + + PGobject tags = new PGobject(); + tags.setType("jsonb"); + tags.setValue("[\"动漫\",\"治愈\"]"); + + Page> page = new Page<>(1, 2, 1); + page.setRecords(List.of(Map.ofEntries( + Map.entry("id", 1L), + Map.entry("character_code", "char_001"), + Map.entry("name", "测试角色"), + Map.entry("description", "简介"), + Map.entry("greeting", "你好"), + Map.entry("avatar_url", "/avatar.png"), + Map.entry("tags", tags), + Map.entry("language", "zh-CN"), + Map.entry("status", 1), + Map.entry("is_official", 1), + Map.entry("is_featured", 0), + Map.entry("is_trending", 0), + Map.entry("trending_score", 10), + Map.entry("chat_count", 42L), + Map.entry("user_count", 3), + Map.entry("is_private", false), + Map.entry("create_id", 9L), + Map.entry("created_at", LocalDateTime.of(2026, 5, 7, 8, 0)), + Map.entry("updated_at", LocalDateTime.of(2026, 5, 7, 9, 0)), + Map.entry("creator_name", "创建者") + ))); + + when(characterService.getPublicCharactersWithCreator( + any(), eq(1), isNull(), isNull(), eq("chat_count"), eq("desc"))) + .thenReturn(page); + + CharacterSearchRequest request = new CharacterSearchRequest(); + request.setPageNum(1); + request.setPageSize(2); + + ApiResponse> response = controller.getPublicCharacters(request); + + assertEquals(200, response.getCode()); + assertEquals("[\"动漫\",\"治愈\"]", response.getData().getList().get(0).getTags()); + } +}