From 7a4086547d715888136e93683370cdecc053a81a Mon Sep 17 00:00:00 2001 From: ziin Date: Wed, 1 Apr 2026 15:11:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=BA=E8=AE=BE=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=9B=BD=E9=99=85=E5=8C=96=E6=9F=A5=E8=AF=A2=E4=B8=8E?= =?UTF-8?q?=E6=9C=AA=E7=99=BB=E5=BD=95=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 6148 -> 8196 bytes src/main/.DS_Store | Bin 6148 -> 6148 bytes .../keyborad/config/SaTokenConfigure.java | 1 + .../controller/CharacterController.java | 60 ++++---- .../listener/CharacterCacheInitializer.java | 4 +- .../mapper/KeyboardCharacterI18nMapper.java | 12 ++ .../mapper/KeyboardUserCharacterMapper.java | 4 +- .../model/entity/KeyboardCharacter.java | 8 - .../model/entity/KeyboardCharacterI18n.java | 71 +++++++++ .../service/KeyboardCharacterI18nService.java | 13 ++ .../service/KeyboardCharacterService.java | 12 +- .../KeyboardCharacterI18nServiceImpl.java | 18 +++ .../impl/KeyboardCharacterServiceImpl.java | 145 ++++++++++++------ .../mapper/KeyboardCharacterI18nMapper.xml | 19 +++ .../mapper/KeyboardCharacter‌Mapper.xml | 7 +- .../mapper/KeyboardUserCharacterMapper.xml | 9 +- 16 files changed, 286 insertions(+), 97 deletions(-) create mode 100644 src/main/java/com/yolo/keyborad/mapper/KeyboardCharacterI18nMapper.java create mode 100644 src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacterI18n.java create mode 100644 src/main/java/com/yolo/keyborad/service/KeyboardCharacterI18nService.java create mode 100644 src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterI18nServiceImpl.java create mode 100644 src/main/resources/mapper/KeyboardCharacterI18nMapper.xml diff --git a/.DS_Store b/.DS_Store index 375783c9769fcf8c8fb78aa3777e13c4914f25c8..1cb011e2a1261ccc0046bf792f3aa6f7aaba8cef 100644 GIT binary patch literal 8196 zcmeHMOK1~882+bCn+>71hbr~9RC==1G*qDo5@S4iF+S>xm>0>~-JLYqm_rCgZ$7|- zcqn)f57MKTig*_f-bGO`UcBf{^z1*6Y-W=UcoNYWnE7Yt`~Uf7zTM33OaOqSo26BN z1pqKGGdmZ@A|x@K<&iWYTNcq0j0b2!3Ceb5HCv=3-nv06pcT*xXa%$aT7kbo0eok( zWQ=+53sjd{0j=eR(P%6hk6y`EX)EjHy=EhwuU}$UXDGD`{d&G|&MLQZbMq&t z>*X!CT;~B+sf;d{&s%PZw$ilemKr=ZD}Y$ch~?%M+U>)M#Im`TOm>#d_Ii@l*OQ%2 z%-DP2(9zSmP1|wl9X4QGZsf8AGveAW?_$lLk2o2Tb6q;SrDCe4Utjhd`kZU($2xSN zW*8pO@h4ve{n+c-x@%Lnf_!Y8Q>d@SPHG?@7}5N_S3y)A)5p!HH`-!MO1wI%aF4*a z_B}%at_KANiUD?*VM{t2Gsjf!2gP@9cDH>!BtFn13=i;%yA#1VQ+(1JL0+rKc_pUu zKG{C_WocLP`uKo13=i-E{}Dy-w?*-Z4)X4~@SXEYOy#|`)%sBF-+vz;@P^?5-dWB& z2@R+ZsT}_?i>wk+Iq&a$J5}G{bM?^y<0u;7+uy@ZVH!MKL+UuwGI*-S#`JOm5o!rJ+E9IgL{A=XWarKIf&iwGut O5Wr>7g;wB?D)0+Hr943Z delta 153 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{MGjdEU6q~50D9QxlfW(r@iwlx+@{@r49TN+e zPd1QYnLJx+=qFF#RkOQ(8w0azOt+W-In diff --git a/src/main/.DS_Store b/src/main/.DS_Store index 63bdf65f4680a96353fd9f0b1a38b93c3f9740ce..baaf8defb43089762e0e0f9a59cb8fb0b818025d 100644 GIT binary patch delta 167 zcmZoMXfc@JFUZEgz`)4BAi$85ZWx@LpIfk5ka;y@JxG{^A&ViAp^PCBCIu8@VBlD& zk1Us)@8Xh_lb-~VStk3&wj=%f> DgWM*E delta 53 zcmZoMXfc@JFUrKgz`)4BAi%&-%233R%#g}ZoK(IsaXI5;0}+> list() { - return ResultUtils.success(characterService.selectListWithRank()); + public BaseResponse> list( + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.selectListWithRank(acceptLanguage)); } @GetMapping("/detail") @Operation(summary = "人设详情", description = "人设详情接口") - public BaseResponse detail(@RequestParam("id") Long id) { - return ResultUtils.success(characterService.getDetailById(id)); + public BaseResponse detail( + @RequestParam("id") Long id, + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.getDetailById(id, acceptLanguage)); } @GetMapping("/listByTag") @Operation(summary = "按标签查询人设列表", description = "按标签查询人设列表接口") - public BaseResponse> listByTag(@RequestParam("tagId") Long tagId) { - return ResultUtils.success(characterService.selectListByTag(tagId)); + public BaseResponse> listByTag( + @RequestParam("tagId") Long tagId, + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.selectListByTag(tagId, acceptLanguage)); } @GetMapping("/listByUser") @Operation(summary = "用户人设列表", description = "用户人设列表接口") - public BaseResponse> userList() { - return ResultUtils.success(characterService.selectListByUserId()); + public BaseResponse> userList( + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.selectListByUserId(acceptLanguage)); } @@ -89,20 +88,27 @@ public class CharacterController { @GetMapping("/listWithNotLogin") @Operation(summary = "未登录用户人设列表", description = "未登录用户人设列表接口按 rank 排名") - public BaseResponse> listWithNotLogin() { - return ResultUtils.success(characterService.selectListWithNotLoginRank()); + public BaseResponse> listWithNotLogin( + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.selectListWithNotLoginRank(acceptLanguage)); } @GetMapping("/detailWithNotLogin") @Operation(summary = "未登录用户人设详情", description = "未登录用户人设详情接口") - public BaseResponse detailWithNotLogin(@RequestParam("id") Long id) { - KeyboardCharacter character = characterService.getById(id); - return ResultUtils.success(BeanUtil.copyProperties(character, KeyboardCharacterRespVO.class)); + public BaseResponse detailWithNotLogin( + @RequestParam("id") Long id, + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.getDetailById(id, acceptLanguage)); } @GetMapping("/listByTagWithNotLogin") @Operation(summary = "未登录用户按标签查询人设列表", description = "未登录用户按标签查询人设列表接口") - public BaseResponse> listByTagWithNotLogin(@RequestParam("tagId") Long tagId) { - return ResultUtils.success(characterService.selectListByTagWithNotLogin(tagId)); + public BaseResponse> listByTagWithNotLogin( + @RequestParam("tagId") Long tagId, + @RequestHeader(value = "Accept-Language", required = false) String acceptLanguage + ) { + return ResultUtils.success(characterService.selectListByTagWithNotLogin(tagId, acceptLanguage)); } -} \ No newline at end of file +} diff --git a/src/main/java/com/yolo/keyborad/listener/CharacterCacheInitializer.java b/src/main/java/com/yolo/keyborad/listener/CharacterCacheInitializer.java index aeaeb6a..271febf 100644 --- a/src/main/java/com/yolo/keyborad/listener/CharacterCacheInitializer.java +++ b/src/main/java/com/yolo/keyborad/listener/CharacterCacheInitializer.java @@ -20,7 +20,7 @@ import java.util.concurrent.TimeUnit; @Slf4j public class CharacterCacheInitializer implements ApplicationRunner { - private static final String CHARACTER_CACHE_KEY = "character:"; + private static final String CHARACTER_CACHE_KEY_PREFIX = "character:"; @Resource private KeyboardCharacterService characterService; @@ -34,7 +34,7 @@ public class CharacterCacheInitializer implements ApplicationRunner { log.info("开始缓存人设列表到Redis..."); List characters = characterService.list(); for (KeyboardCharacter character : characters) { - String key = CHARACTER_CACHE_KEY + character.getId(); + String key = CHARACTER_CACHE_KEY_PREFIX + character.getId(); redisTemplate.opsForValue().set(key, character, 5, TimeUnit.MINUTES); } log.info("人设列表缓存完成,共缓存 {} 条记录", characters.size()); diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardCharacterI18nMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardCharacterI18nMapper.java new file mode 100644 index 0000000..554014e --- /dev/null +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardCharacterI18nMapper.java @@ -0,0 +1,12 @@ +package com.yolo.keyborad.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yolo.keyborad.model.entity.KeyboardCharacterI18n; + +/* +* @author: ziin +* @date: 2026/4/1 14:13 +*/ + +public interface KeyboardCharacterI18nMapper extends BaseMapper { +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java index d70f9e7..7c3f6c6 100644 --- a/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java +++ b/src/main/java/com/yolo/keyborad/mapper/KeyboardUserCharacterMapper.java @@ -14,11 +14,11 @@ import java.util.List; public interface KeyboardUserCharacterMapper extends BaseMapper { - List selectByUserId(@Param("loginId") long loginId); + List selectByUserId(@Param("loginId") long loginId, @Param("locale") String locale); void updateSortByIdAndUserId(@Param("sort") Integer[] sort,@Param("userId") long userId); List selectSortByUserId(@Param("userId") Long userId); void deleteByIdAndUserId(@Param("id") Long id, @Param("userId") long userId); -} \ No newline at end of file +} diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java index 7d8b263..114e9da 100644 --- a/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacter.java @@ -21,14 +21,6 @@ public class KeyboardCharacter { @Schema(description="主键 Id") private Long id; - @TableField(value = "character_name") - @Schema(description="标题") - private String characterName; - - @TableField(value = "\"character_background\"") - @Schema(description="背景描述") - private String characterBackground; - @TableField(value = "avatar_url") @Schema(description="角色头像") private String avatarUrl; diff --git a/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacterI18n.java b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacterI18n.java new file mode 100644 index 0000000..f05d86a --- /dev/null +++ b/src/main/java/com/yolo/keyborad/model/entity/KeyboardCharacterI18n.java @@ -0,0 +1,71 @@ +package com.yolo.keyborad.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.Date; +import lombok.Data; + +/* +* @author: ziin +* @date: 2026/4/1 14:13 +*/ + +/** + * 键盘人设国际化内容表 + */ +@Schema(description="键盘人设国际化内容表") +@Data +@TableName(value = "keyboard_character_i18n") +public class KeyboardCharacterI18n { + /** + * 主键 Id + */ + @TableId(value = "id", type = IdType.AUTO) + @Schema(description="主键 Id") + private Long id; + + /** + * 角色主表id + */ + @TableField(value = "character_id") + @Schema(description="角色主表id") + private Long characterId; + + /** + * 语言标识,如 zh-CN/en-US/ja-JP + */ + @TableField(value = "\"locale\"") + @Schema(description="语言标识,如 zh-CN/en-US/ja-JP") + private String locale; + + /** + * 标题 + */ + @TableField(value = "character_name") + @Schema(description="标题") + private String characterName; + + /** + * 背景描述 + */ + @TableField(value = "character_background") + @Schema(description="背景描述") + private String characterBackground; + + /** + * 创建时间 + */ + @TableField(value = "created_at") + @Schema(description="创建时间") + private Date createdAt; + + /** + * 更新时间 + */ + @TableField(value = "updated_at") + @Schema(description="更新时间") + private Date updatedAt; +} \ No newline at end of file diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardCharacterI18nService.java b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterI18nService.java new file mode 100644 index 0000000..1d50915 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterI18nService.java @@ -0,0 +1,13 @@ +package com.yolo.keyborad.service; + +import com.yolo.keyborad.model.entity.KeyboardCharacterI18n; +import com.baomidou.mybatisplus.extension.service.IService; + /* +* @author: ziin +* @date: 2026/4/1 14:13 +*/ + +public interface KeyboardCharacterI18nService extends IService{ + + +} diff --git a/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java index 489f5c2..9f3b31a 100644 --- a/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java +++ b/src/main/java/com/yolo/keyborad/service/KeyboardCharacterService.java @@ -18,11 +18,11 @@ import java.util.List; public interface KeyboardCharacterService extends IService{ - List selectListWithRank(); + List selectListWithRank(String acceptLanguage); - List selectListByTag(Long tagId); + List selectListByTag(Long tagId, String acceptLanguage); - List selectListByUserId(); + List selectListByUserId(String acceptLanguage); void updateSort(KeyboardUserCharacterSortUpdateDTO sortUpdateDTO); @@ -30,11 +30,11 @@ public interface KeyboardCharacterService extends IService{ void removeUserCharacter(Long id); - List selectListWithNotLoginRank(); + List selectListWithNotLoginRank(String acceptLanguage); - List selectListByTagWithNotLogin(Long tagId); + List selectListByTagWithNotLogin(Long tagId, String acceptLanguage); void addDefaultUserCharacter(Long userId); - KeyboardCharacterRespVO getDetailById(Long id); + KeyboardCharacterRespVO getDetailById(Long id, String acceptLanguage); } diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterI18nServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterI18nServiceImpl.java new file mode 100644 index 0000000..6ba2353 --- /dev/null +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterI18nServiceImpl.java @@ -0,0 +1,18 @@ +package com.yolo.keyborad.service.impl; + +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yolo.keyborad.model.entity.KeyboardCharacterI18n; +import com.yolo.keyborad.mapper.KeyboardCharacterI18nMapper; +import com.yolo.keyborad.service.KeyboardCharacterI18nService; +/* +* @author: ziin +* @date: 2026/4/1 14:13 +*/ + +@Service +public class KeyboardCharacterI18nServiceImpl extends ServiceImpl implements KeyboardCharacterI18nService{ + +} diff --git a/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java index cad3a18..134c54d 100644 --- a/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java +++ b/src/main/java/com/yolo/keyborad/service/impl/KeyboardCharacterServiceImpl.java @@ -2,31 +2,35 @@ package com.yolo.keyborad.service.impl; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.yolo.keyborad.common.ErrorCode; import com.yolo.keyborad.exception.BusinessException; import com.yolo.keyborad.mapper.KeyboardCharacterMapper; +import com.yolo.keyborad.mapper.KeyboardCharacterI18nMapper; import com.yolo.keyborad.mapper.KeyboardUserCharacterMapper; import com.yolo.keyborad.mapper.KeyboardUserSortMapper; import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterAddDTO; import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO; -import com.yolo.keyborad.model.entity.KeyboardUser; import com.yolo.keyborad.model.entity.KeyboardUserCharacter; +import com.yolo.keyborad.model.entity.KeyboardCharacterI18n; import com.yolo.keyborad.model.vo.character.KeyboardCharacterRespVO; import com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO; +import com.yolo.keyborad.utils.RequestLocaleUtils; import jakarta.annotation.Resource; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yolo.keyborad.model.entity.KeyboardCharacter; import com.yolo.keyborad.service.KeyboardCharacterService; +import org.springframework.util.StringUtils; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; @@ -38,7 +42,9 @@ import java.util.stream.Stream; @Service public class KeyboardCharacterServiceImpl extends ServiceImpl implements KeyboardCharacterService{ - private static final String CHARACTER_CACHE_KEY = "character:"; + private static final String CHARACTER_CACHE_KEY_PREFIX = "character:"; + private static final String CHARACTER_LIST_CACHE_KEY = "character:list:all"; + private static final String CHARACTER_TAG_CACHE_KEY_PREFIX = "character:list:tag:"; @Resource private KeyboardCharacterMapper keyboardCharacterMapper; @@ -49,12 +55,15 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl redisTemplate; @Override public KeyboardCharacter getById(java.io.Serializable id) { - String key = CHARACTER_CACHE_KEY + id; + String key = CHARACTER_CACHE_KEY_PREFIX + id; KeyboardCharacter character = (KeyboardCharacter) redisTemplate.opsForValue().get(key); if (character == null) { character = super.getById(id); @@ -72,12 +81,11 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListWithRank() { + public List selectListWithRank(String acceptLanguage) { // 获取当前登录用户ID long userId = StpUtil.getLoginIdAsLong(); - // 定义缓存key,用于存储所有人设列表 - String cacheKey = "character:list:all"; + String cacheKey = CHARACTER_LIST_CACHE_KEY; // 尝试从Redis缓存中获取人设列表 List keyboardCharacters = (List) redisTemplate.opsForValue().get(cacheKey); @@ -95,17 +103,12 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl userCharacterVOList = keyboardUserCharacterMapper.selectByUserId(userId); + List userCharacterVOList = keyboardUserCharacterMapper.selectByUserId(userId, null); // 将KeyboardCharacter实体列表转换为KeyboardCharacterRespVO响应对象列表 - List keyboardCharacterRespVOS = BeanUtil.copyToList(keyboardCharacters, KeyboardCharacterRespVO.class); + List keyboardCharacterRespVOS = buildCharacterRespList(keyboardCharacters, acceptLanguage); - // 遍历人设列表,标记每个人设是否已被当前用户添加 - keyboardCharacterRespVOS.forEach(character -> { - // 检查用户已添加列表中是否存在该人设ID - character.setAdded(userCharacterVOList.stream().anyMatch(userCharacter -> - userCharacter.getCharacterId().equals(character.getId()))); - }); + markAddedCharacters(keyboardCharacterRespVOS, userCharacterVOList); return keyboardCharacterRespVOS; } @@ -118,9 +121,8 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListByTag(Long tagId) { - // 构建缓存key,用于存储指定标签的人设列表 - String cacheKey = "character:list:tag:" + tagId; + public List selectListByTag(Long tagId, String acceptLanguage) { + String cacheKey = CHARACTER_TAG_CACHE_KEY_PREFIX + tagId; // 尝试从Redis缓存中获取指定标签的人设列表 List keyboardCharacters = (List) redisTemplate.opsForValue().get(cacheKey); @@ -142,25 +144,21 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl userCharacterVOList = keyboardUserCharacterMapper.selectByUserId(userId); + List userCharacterVOList = keyboardUserCharacterMapper.selectByUserId(userId, null); // 将KeyboardCharacter实体列表转换为KeyboardCharacterRespVO响应对象列表 - List keyboardCharacterRespVOS = BeanUtil.copyToList(keyboardCharacters, KeyboardCharacterRespVO.class); + List keyboardCharacterRespVOS = buildCharacterRespList(keyboardCharacters, acceptLanguage); - // 遍历人设列表,标记每个人设是否已被当前用户添加 - keyboardCharacterRespVOS.forEach(character -> { - // 检查用户已添加列表中是否存在该人设ID - character.setAdded(userCharacterVOList.stream().anyMatch(userCharacter -> - userCharacter.getCharacterId().equals(character.getId()))); - }); + markAddedCharacters(keyboardCharacterRespVOS, userCharacterVOList); return keyboardCharacterRespVOS; } @Override - public List selectListByUserId() { + public List selectListByUserId(String acceptLanguage) { long loginId = StpUtil.getLoginIdAsLong(); - return keyboardUserCharacterMapper.selectByUserId(loginId); + String locale = RequestLocaleUtils.resolveLanguage(acceptLanguage); + return keyboardUserCharacterMapper.selectByUserId(loginId, locale); } @Override @@ -225,9 +223,8 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListWithNotLoginRank() { - // 先从缓存获取所有人设列表 - String cacheKey = "character:list:all"; + public List selectListWithNotLoginRank(String acceptLanguage) { + String cacheKey = CHARACTER_LIST_CACHE_KEY; List keyboardCharacters = (List) redisTemplate.opsForValue().get(cacheKey); if (keyboardCharacters == null) { @@ -240,13 +237,12 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl selectListByTagWithNotLogin(Long tagId) { - // 先从缓存获取指定标签的人设列表 - String cacheKey = "character:list:tag:" + tagId; + public List selectListByTagWithNotLogin(Long tagId, String acceptLanguage) { + String cacheKey = CHARACTER_TAG_CACHE_KEY_PREFIX + tagId; List keyboardCharacters = (List) redisTemplate.opsForValue().get(cacheKey); if (keyboardCharacters == null) { @@ -260,7 +256,7 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl limit = selectListWithNotLoginRank().stream().limit(5); + Stream limit = selectListWithNotLoginRank(null).stream().limit(5); // 遍历前5个人设,为用户添加默认人设 limit.forEach(character -> { @@ -290,20 +286,83 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl() .eq(KeyboardUserCharacter::getCharacterId, id) .eq(KeyboardUserCharacter::getUserId, userId)); - // 设置是否已添加的标记 respVO.setAdded(userCharacter != null); return respVO; } + + private List buildCharacterRespList(List keyboardCharacters, String acceptLanguage) { + if (keyboardCharacters == null || keyboardCharacters.isEmpty()) { + return Collections.emptyList(); + } + List respVOS = BeanUtil.copyToList(keyboardCharacters, KeyboardCharacterRespVO.class); + applyI18n(respVOS, acceptLanguage); + return respVOS; + } + + private void applyI18n(List respVOS, String acceptLanguage) { + if (respVOS == null || respVOS.isEmpty()) { + return; + } + String locale = RequestLocaleUtils.resolveLanguage(acceptLanguage); + if (!StringUtils.hasText(locale)) { + return; + } + + List characterIds = respVOS.stream() + .map(KeyboardCharacterRespVO::getId) + .toList(); + Map i18nMap = loadI18nMap(characterIds, locale); + respVOS.forEach(respVO -> { + KeyboardCharacterI18n i18n = i18nMap.get(respVO.getId()); + if (i18n == null) { + return; + } + respVO.setCharacterName(i18n.getCharacterName()); + respVO.setCharacterBackground(i18n.getCharacterBackground()); + }); + } + + private void markAddedCharacters(List respVOS, List userCharacterVOList) { + if (respVOS == null || respVOS.isEmpty()) { + return; + } + Set addedCharacterIds = new HashSet<>(); + if (userCharacterVOList != null && !userCharacterVOList.isEmpty()) { + userCharacterVOList.forEach(userCharacter -> addedCharacterIds.add(userCharacter.getCharacterId())); + } + respVOS.forEach(character -> character.setAdded(addedCharacterIds.contains(character.getId()))); + } + + private Map loadI18nMap(List characterIds, String locale) { + if (characterIds == null || characterIds.isEmpty()) { + return Collections.emptyMap(); + } + List i18nList = keyboardCharacterI18nMapper.selectList( + new LambdaQueryWrapper() + .eq(KeyboardCharacterI18n::getLocale, locale) + .in(KeyboardCharacterI18n::getCharacterId, characterIds) + ); + if (i18nList == null || i18nList.isEmpty()) { + return Collections.emptyMap(); + } + Map i18nMap = new LinkedHashMap<>(); + i18nList.forEach(item -> i18nMap.put(item.getCharacterId(), item)); + return i18nMap; + } } diff --git a/src/main/resources/mapper/KeyboardCharacterI18nMapper.xml b/src/main/resources/mapper/KeyboardCharacterI18nMapper.xml new file mode 100644 index 0000000..6375eb0 --- /dev/null +++ b/src/main/resources/mapper/KeyboardCharacterI18nMapper.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + id, character_id, "locale", character_name, character_background, created_at, updated_at + + \ No newline at end of file diff --git a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml index fc9e2a4..56f0086 100644 --- a/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml +++ b/src/main/resources/mapper/KeyboardCharacter‌Mapper.xml @@ -4,8 +4,6 @@ - - @@ -17,7 +15,6 @@ - id, character_name, "character_background", avatar_url, download, tag, deleted, created_at, - updated_at, prompt, "rank",emoji + id, avatar_url, download, tag, deleted, created_at, updated_at, prompt, "rank", emoji - \ No newline at end of file + diff --git a/src/main/resources/mapper/KeyboardUserCharacterMapper.xml b/src/main/resources/mapper/KeyboardUserCharacterMapper.xml index 85d206c..dd273dc 100644 --- a/src/main/resources/mapper/KeyboardUserCharacterMapper.xml +++ b/src/main/resources/mapper/KeyboardUserCharacterMapper.xml @@ -9,13 +9,14 @@ SELECT kuc.id, kuc.character_id, - kc.character_name, + kci.character_name, kuc.emoji FROM keyboard_user_character kuc JOIN keyboard_user_sort kus ON kus.user_id = kuc.user_id - LEFT JOIN keyboard_character kc - ON kuc.character_id = kc.id + LEFT JOIN keyboard_character_i18n kci + ON kuc.character_id = kci.character_id + AND kci."locale" = #{locale} WHERE kuc.user_id = #{loginId} AND kuc.deleted = FALSE ORDER BY array_position(kus.user_characteu_id_sort, kuc.id) NULLS LAST; @@ -39,4 +40,4 @@ WHERE id = #{id} AND user_id = #{userId} - \ No newline at end of file +