feat(character): 添加用户人设接口及排序管理
新增 /character/addUserCharacter 端点,支持用户将人设加入个人列表并自动维护排序数组。引入 KeyboardUserCharacterAddDTO、KeyboardUserSortMapper 及相关错误码,实现事务级插入与排序更新。
This commit is contained in:
@@ -32,7 +32,8 @@ public enum ErrorCode {
|
|||||||
USER_INFO_UPDATE_FAILED(50002, "用户信息更新失败"),
|
USER_INFO_UPDATE_FAILED(50002, "用户信息更新失败"),
|
||||||
PASSWORD_OR_MAIL_ERROR(50003,"密码或邮箱错误" ),
|
PASSWORD_OR_MAIL_ERROR(50003,"密码或邮箱错误" ),
|
||||||
SEND_MAIL_FAILED(50004,"邮件发送失败" ),
|
SEND_MAIL_FAILED(50004,"邮件发送失败" ),
|
||||||
CONFIRM_PASSWORD_NOT_MATCH(50005,"重复密码不匹配" );
|
CONFIRM_PASSWORD_NOT_MATCH(50005,"重复密码不匹配" ),
|
||||||
|
USER_CHARACTER_ADD_ERROR(50006,"添加用户键盘字符失败" );
|
||||||
/**
|
/**
|
||||||
* 状态码
|
* 状态码
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
|||||||
"/user/updateInfo",
|
"/user/updateInfo",
|
||||||
"/user/detail",
|
"/user/detail",
|
||||||
"/user/register",
|
"/user/register",
|
||||||
"/character/updateUserCharacterSort"
|
"/character/updateUserCharacterSort",
|
||||||
|
"/character/addUserCharacter"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cn.dev33.satoken.stp.StpUtil;
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import com.yolo.keyborad.common.BaseResponse;
|
import com.yolo.keyborad.common.BaseResponse;
|
||||||
import com.yolo.keyborad.common.ResultUtils;
|
import com.yolo.keyborad.common.ResultUtils;
|
||||||
|
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterAddDTO;
|
||||||
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterDTO;
|
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterDTO;
|
||||||
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO;
|
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO;
|
||||||
import com.yolo.keyborad.model.entity.KeyboardCharacter;
|
import com.yolo.keyborad.model.entity.KeyboardCharacter;
|
||||||
@@ -49,7 +50,7 @@ public class CharacterController {
|
|||||||
@Operation(summary = "人设详情", description = "人设详情接口")
|
@Operation(summary = "人设详情", description = "人设详情接口")
|
||||||
public BaseResponse<KeyboardCharacterRespVO> detail(@RequestParam("id") Long id) {
|
public BaseResponse<KeyboardCharacterRespVO> detail(@RequestParam("id") Long id) {
|
||||||
KeyboardCharacter character = characterService.getById(id);
|
KeyboardCharacter character = characterService.getById(id);
|
||||||
return ResultUtils.success(BeanUtil.copyProperties(character ,KeyboardCharacterRespVO.class));
|
return ResultUtils.success(BeanUtil.copyProperties(character, KeyboardCharacterRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/listByTag")
|
@GetMapping("/listByTag")
|
||||||
@@ -67,10 +68,16 @@ public class CharacterController {
|
|||||||
|
|
||||||
|
|
||||||
@PostMapping("/updateUserCharacterSort")
|
@PostMapping("/updateUserCharacterSort")
|
||||||
@Operation(summary = "更新用户人设排序",description = "更新用户人设排序接口")
|
@Operation(summary = "更新用户人设排序", description = "更新用户人设排序接口")
|
||||||
public BaseResponse<Boolean> updateUserCharacterSort(@RequestBody KeyboardUserCharacterSortUpdateDTO sortUpdateDTO) {
|
public BaseResponse<Boolean> updateUserCharacterSort(@RequestBody KeyboardUserCharacterSortUpdateDTO sortUpdateDTO) {
|
||||||
characterService.updateSort(sortUpdateDTO);
|
characterService.updateSort(sortUpdateDTO);
|
||||||
return ResultUtils.success(true);
|
return ResultUtils.success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@PostMapping("/addUserCharacter")
|
||||||
|
@Operation(summary = "添加用户人设", description = "添加用户人设接口")
|
||||||
|
public BaseResponse<Boolean> addUserCharacter(@RequestBody KeyboardUserCharacterAddDTO addDTO) {
|
||||||
|
characterService.addUserCharacter(addDTO);
|
||||||
|
return ResultUtils.success(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,4 +18,5 @@ public interface KeyboardUserCharacterMapper extends BaseMapper<KeyboardUserChar
|
|||||||
|
|
||||||
void updateSortByIdAndUserId(@Param("sort") Integer[] sort,@Param("userId") long userId);
|
void updateSortByIdAndUserId(@Param("sort") Integer[] sort,@Param("userId") long userId);
|
||||||
|
|
||||||
|
List<Long> selectSortByUserId(@Param("userId") Long userId);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.yolo.keyborad.mapper;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Insert;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface KeyboardUserSortMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询某个用户的人设排序(按顺序展开成列表)
|
||||||
|
*/
|
||||||
|
List<Long> selectSortByUserId(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户排序数组
|
||||||
|
*/
|
||||||
|
int updateSortByUserId(@Param("userId") Long userId,
|
||||||
|
@Param("sort") Long[] sort);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 插入一条新的用户排序记录
|
||||||
|
*/
|
||||||
|
int insertUserSort(@Param("userId") Long userId,
|
||||||
|
@Param("sort") Long[] sort);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.yolo.keyborad.model.dto.userCharacter;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Schema(description = "用户键盘顺序更新 DTO")
|
||||||
|
@Data
|
||||||
|
public class KeyboardUserCharacterAddDTO {
|
||||||
|
|
||||||
|
@Schema(description="键盘人设 id")
|
||||||
|
private Long characterId;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.yolo.keyborad.service;
|
package com.yolo.keyborad.service;
|
||||||
|
|
||||||
|
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterAddDTO;
|
||||||
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO;
|
import com.yolo.keyborad.model.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO;
|
||||||
import com.yolo.keyborad.model.entity.KeyboardCharacter;
|
import com.yolo.keyborad.model.entity.KeyboardCharacter;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
@@ -23,4 +24,6 @@ public interface KeyboardCharacterService extends IService<KeyboardCharacter>{
|
|||||||
List<KeyboardUserCharacterVO> selectListByUserId();
|
List<KeyboardUserCharacterVO> selectListByUserId();
|
||||||
|
|
||||||
void updateSort(KeyboardUserCharacterSortUpdateDTO sortUpdateDTO);
|
void updateSort(KeyboardUserCharacterSortUpdateDTO sortUpdateDTO);
|
||||||
|
|
||||||
|
void addUserCharacter(KeyboardUserCharacterAddDTO addDTO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
package com.yolo.keyborad.service.impl;
|
package com.yolo.keyborad.service.impl;
|
||||||
|
|
||||||
import cn.dev33.satoken.stp.StpUtil;
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
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.KeyboardCharacterMapper;
|
||||||
import com.yolo.keyborad.mapper.KeyboardUserCharacterMapper;
|
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.dto.userCharacter.KeyboardUserCharacterSortUpdateDTO;
|
||||||
|
import com.yolo.keyborad.model.entity.KeyboardUser;
|
||||||
import com.yolo.keyborad.model.entity.KeyboardUserCharacter;
|
import com.yolo.keyborad.model.entity.KeyboardUserCharacter;
|
||||||
import com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO;
|
import com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@@ -32,6 +38,9 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterM
|
|||||||
@Resource
|
@Resource
|
||||||
private KeyboardUserCharacterMapper keyboardUserCharacterMapper;
|
private KeyboardUserCharacterMapper keyboardUserCharacterMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private KeyboardUserSortMapper keyboardUserSortMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<KeyboardCharacter> selectListWithRank() {
|
public List<KeyboardCharacter> selectListWithRank() {
|
||||||
return keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
|
return keyboardCharacterMapper.selectList(new LambdaQueryWrapper<KeyboardCharacter>()
|
||||||
@@ -50,7 +59,6 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterM
|
|||||||
@Override
|
@Override
|
||||||
public List<KeyboardUserCharacterVO> selectListByUserId() {
|
public List<KeyboardUserCharacterVO> selectListByUserId() {
|
||||||
long loginId = StpUtil.getLoginIdAsLong();
|
long loginId = StpUtil.getLoginIdAsLong();
|
||||||
|
|
||||||
return keyboardUserCharacterMapper.selectByUserId(loginId);
|
return keyboardUserCharacterMapper.selectByUserId(loginId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,4 +72,42 @@ public class KeyboardCharacterServiceImpl extends ServiceImpl<KeyboardCharacterM
|
|||||||
long loginIdAsLong = StpUtil.getLoginIdAsLong();
|
long loginIdAsLong = StpUtil.getLoginIdAsLong();
|
||||||
keyboardUserCharacterMapper.updateSortByIdAndUserId(sortArray, loginIdAsLong);
|
keyboardUserCharacterMapper.updateSortByIdAndUserId(sortArray, loginIdAsLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void addUserCharacter(KeyboardUserCharacterAddDTO addDTO) {
|
||||||
|
// 1. 插入用户人设
|
||||||
|
KeyboardUserCharacter keyboardUserCharacter = BeanUtil.copyProperties(addDTO, KeyboardUserCharacter.class);
|
||||||
|
long userId = StpUtil.getLoginIdAsLong();
|
||||||
|
keyboardUserCharacter.setUserId(userId);
|
||||||
|
|
||||||
|
int insert = keyboardUserCharacterMapper.insert(keyboardUserCharacter);
|
||||||
|
if (insert != 1) {
|
||||||
|
log.error("用户人设添加失败, userId={}");
|
||||||
|
throw new BusinessException(ErrorCode.USER_CHARACTER_ADD_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新插入这条记录的主键 id(MyBatis-Plus 会自动回填)
|
||||||
|
Long newId = keyboardUserCharacter.getId();
|
||||||
|
|
||||||
|
// 2. 查询用户当前的排序(展开数组)
|
||||||
|
List<Long> oldSortList = keyboardUserSortMapper.selectSortByUserId(userId);
|
||||||
|
// selectSortByUserId 用 unnest(user_characteu_id_sort) 实现,见下面 mapper 部分
|
||||||
|
|
||||||
|
// 3. 组装新的排序:在末尾加上新 id
|
||||||
|
List<Long> newSortList = new ArrayList<>();
|
||||||
|
if (oldSortList != null && !oldSortList.isEmpty()) {
|
||||||
|
newSortList.addAll(oldSortList);
|
||||||
|
}
|
||||||
|
newSortList.add(newId);
|
||||||
|
|
||||||
|
Long[] newSortArray = newSortList.toArray(new Long[0]);
|
||||||
|
|
||||||
|
// 4. 更新 keyboard_user_sort,如果没有记录就插入一条
|
||||||
|
int updated = keyboardUserSortMapper.updateSortByUserId(userId, newSortArray);
|
||||||
|
if (updated == 0) {
|
||||||
|
// 说明该 userId 还没有排序记录,插入一条
|
||||||
|
keyboardUserSortMapper.insertUserSort(userId, newSortArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,39 +2,35 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.yolo.keyborad.mapper.KeyboardUserCharacterMapper">
|
<mapper namespace="com.yolo.keyborad.mapper.KeyboardUserCharacterMapper">
|
||||||
|
|
||||||
<resultMap id="KeyboardUserCharacterVOMap"
|
|
||||||
type="com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO">
|
|
||||||
|
|
||||||
<id column="id" property="id"/>
|
|
||||||
|
|
||||||
<!-- keyboard_character 表的列名,根据你的实际字段调整 -->
|
|
||||||
<result column="character_name" property="characterName"/>
|
|
||||||
|
|
||||||
<!-- 关键:ARRAY 字段明确指定 jdbcType + typeHandler -->
|
|
||||||
<result column="sort"
|
|
||||||
jdbcType="ARRAY"
|
|
||||||
typeHandler="org.apache.ibatis.type.ArrayTypeHandler"/>
|
|
||||||
<result column="emoji" property="emoji"/>
|
|
||||||
</resultMap>
|
|
||||||
|
|
||||||
<update id="updateSortByIdAndUserId">
|
|
||||||
UPDATE keyboard_user_character
|
|
||||||
SET sort = #{sort,jdbcType=ARRAY}
|
|
||||||
where user_id = #{userId}
|
|
||||||
AND deleted = FALSE
|
|
||||||
</update>
|
|
||||||
|
|
||||||
|
|
||||||
<select id="selectByUserId"
|
<select id="selectByUserId"
|
||||||
resultMap="KeyboardUserCharacterVOMap">
|
resultType="com.yolo.keyborad.model.vo.character.KeyboardUserCharacterVO">
|
||||||
SELECT
|
SELECT
|
||||||
kuc.id,
|
kuc.id,
|
||||||
|
kuc.character_id,
|
||||||
kc.character_name,
|
kc.character_name,
|
||||||
kuc.sort,
|
|
||||||
kuc.emoji
|
kuc.emoji
|
||||||
FROM keyboard_user_character AS kuc
|
FROM keyboard_user_character kuc
|
||||||
LEFT JOIN keyboard_character AS kc ON kuc.character_id = kc.id
|
JOIN keyboard_user_sort kus
|
||||||
|
ON kus.user_id = kuc.user_id
|
||||||
|
LEFT JOIN keyboard_character kc
|
||||||
|
ON kuc.character_id = kc.id
|
||||||
WHERE kuc.user_id = #{loginId}
|
WHERE kuc.user_id = #{loginId}
|
||||||
AND kuc.deleted = FALSE
|
AND kuc.deleted = FALSE
|
||||||
|
ORDER BY array_position(kus.user_characteu_id_sort, kuc.id) NULLS LAST;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateSortByIdAndUserId">
|
||||||
|
UPDATE keyboard_user_sort
|
||||||
|
SET user_characteu_id_sort = #{sort,jdbcType=ARRAY}
|
||||||
|
where user_id = #{userId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
|
||||||
|
<select id="selectSortByUserId" resultType="java.lang.Long">
|
||||||
|
SELECT unnest(user_characteu_id_sort)
|
||||||
|
FROM keyboard_user_sort
|
||||||
|
WHERE user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
22
src/main/resources/mapper/KeyboardUserSortMapper.xml
Normal file
22
src/main/resources/mapper/KeyboardUserSortMapper.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?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="com.yolo.keyborad.mapper.KeyboardUserSortMapper">
|
||||||
|
<!-- 展开数组为多行:返回 List<Long> -->
|
||||||
|
<select id="selectSortByUserId" resultType="java.lang.Long">
|
||||||
|
SELECT unnest(user_characteu_id_sort)
|
||||||
|
FROM keyboard_user_sort
|
||||||
|
WHERE user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<update id="updateSortByUserId">
|
||||||
|
UPDATE keyboard_user_sort
|
||||||
|
SET user_characteu_id_sort = #{sort, jdbcType=ARRAY}
|
||||||
|
WHERE user_id = #{userId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<insert id="insertUserSort">
|
||||||
|
INSERT INTO keyboard_user_sort (user_id, user_characteu_id_sort)
|
||||||
|
VALUES (#{userId}, #{sort, jdbcType=ARRAY})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user