From c7bc34817aa0e0a25cda5cd5f01fc8f791c461f9 Mon Sep 17 00:00:00 2001 From: ziin Date: Wed, 24 Dec 2025 14:21:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(character):=20=E6=96=B0=E5=A2=9E=E9=94=AE?= =?UTF-8?q?=E7=9B=98=E4=BA=BA=E8=AE=BE=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 Controller/Service/Mapper/VO/DO 全套模块,支持人设分页查询、保存及详情接口,并补充 CHARACTER_NOT_EXISTS 错误码。 --- .../KeyboardCharacterController.java | 104 ++++++++++++++++++ .../vo/KeyboardCharacterPageReqVO.java | 46 ++++++++ .../character/vo/KeyboardCharacterRespVO.java | 59 ++++++++++ .../vo/KeyboardCharacterSaveReqVO.java | 47 ++++++++ .../character/KeyboardCharacterDO.java | 73 ++++++++++++ .../character/KeyboardCharacterMapper.java | 35 ++++++ .../character/KeyboardCharacterService.java | 61 ++++++++++ .../KeyboardCharacterServiceImpl.java | 81 ++++++++++++++ .../character/KeyboardCharacterMapper.xml | 12 ++ .../infra/enums/ErrorCodeConstants.java | 1 + 10 files changed, 519 insertions(+) create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/KeyboardCharacterController.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterPageReqVO.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterRespVO.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterSaveReqVO.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/character/KeyboardCharacterDO.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/character/KeyboardCharacterMapper.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterService.java create mode 100644 keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterServiceImpl.java create mode 100644 keyboard-server/src/main/resources/mapper/character/KeyboardCharacterMapper.xml diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/KeyboardCharacterController.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/KeyboardCharacterController.java new file mode 100644 index 0000000..2324cf4 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/KeyboardCharacterController.java @@ -0,0 +1,104 @@ +package com.yolo.keyboard.controller.admin.character; + +import org.springframework.web.bind.annotation.*; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.security.access.prepost.PreAuthorize; +import io.swagger.v3.oas.annotations.tags.Tag; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Operation; + +import jakarta.validation.constraints.*; +import jakarta.validation.*; +import jakarta.servlet.http.*; +import java.util.*; +import java.io.IOException; + +import com.yolo.keyboard.framework.common.pojo.PageParam; +import com.yolo.keyboard.framework.common.pojo.PageResult; +import com.yolo.keyboard.framework.common.pojo.CommonResult; +import com.yolo.keyboard.framework.common.util.object.BeanUtils; +import static com.yolo.keyboard.framework.common.pojo.CommonResult.success; + +import com.yolo.keyboard.framework.excel.core.util.ExcelUtils; + +import com.yolo.keyboard.framework.apilog.core.annotation.ApiAccessLog; +import static com.yolo.keyboard.framework.apilog.core.enums.OperateTypeEnum.*; + +import com.yolo.keyboard.controller.admin.character.vo.*; +import com.yolo.keyboard.dal.dataobject.character.KeyboardCharacterDO; +import com.yolo.keyboard.service.character.KeyboardCharacterService; + +@Tag(name = "管理后台 - 键盘人设") +@RestController +@RequestMapping("/keyboard/character") +@Validated +public class KeyboardCharacterController { + + @Resource + private KeyboardCharacterService characterService; + + @PostMapping("/create") + @Operation(summary = "创建键盘人设") + @PreAuthorize("@ss.hasPermission('keyboard:character:create')") + public CommonResult createCharacter(@Valid @RequestBody KeyboardCharacterSaveReqVO createReqVO) { + return success(characterService.createCharacter(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新键盘人设") + @PreAuthorize("@ss.hasPermission('keyboard:character:update')") + public CommonResult updateCharacter(@Valid @RequestBody KeyboardCharacterSaveReqVO updateReqVO) { + characterService.updateCharacter(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除键盘人设") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('keyboard:character:delete')") + public CommonResult deleteCharacter(@RequestParam("id") Long id) { + characterService.deleteCharacter(id); + return success(true); + } + + @DeleteMapping("/delete-list") + @Parameter(name = "ids", description = "编号", required = true) + @Operation(summary = "批量删除键盘人设") + @PreAuthorize("@ss.hasPermission('keyboard:character:delete')") + public CommonResult deleteCharacterList(@RequestParam("ids") List ids) { + characterService.deleteCharacterListByIds(ids); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得键盘人设") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('keyboard:character:query')") + public CommonResult getCharacter(@RequestParam("id") Long id) { + KeyboardCharacterDO character = characterService.getCharacter(id); + return success(BeanUtils.toBean(character, KeyboardCharacterRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得键盘人设分页") + @PreAuthorize("@ss.hasPermission('keyboard:character:query')") + public CommonResult> getCharacterPage(@Valid KeyboardCharacterPageReqVO pageReqVO) { + PageResult pageResult = characterService.getCharacterPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, KeyboardCharacterRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出键盘人设 Excel") + @PreAuthorize("@ss.hasPermission('keyboard:character:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportCharacterExcel(@Valid KeyboardCharacterPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = characterService.getCharacterPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "键盘人设.xls", "数据", KeyboardCharacterRespVO.class, + BeanUtils.toBean(list, KeyboardCharacterRespVO.class)); + } + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterPageReqVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterPageReqVO.java new file mode 100644 index 0000000..0f481d7 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterPageReqVO.java @@ -0,0 +1,46 @@ +package com.yolo.keyboard.controller.admin.character.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import com.yolo.keyboard.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +import static com.yolo.keyboard.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 键盘人设分页 Request VO") +@Data +public class KeyboardCharacterPageReqVO extends PageParam { + + @Schema(description = "标题", example = "王五") + private String characterName; + + @Schema(description = "背景描述") + private String characterBackground; + + @Schema(description = "角色头像", example = "https://www.iocoder.cn") + private String avatarUrl; + + @Schema(description = "下载次数") + private String download; + + @Schema(description = "标签id") + private Long tag; + + @Schema(description = "创建时间") + private LocalDateTime createdAt; + + @Schema(description = "更新时间") + private LocalDateTime updatedAt; + + @Schema(description = "人设提示词") + private String prompt; + + @Schema(description = "排名顺序") + private Integer rank; + + @Schema(description = "emoji 标签") + private String emoji; + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterRespVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterRespVO.java new file mode 100644 index 0000000..508f880 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterRespVO.java @@ -0,0 +1,59 @@ +package com.yolo.keyboard.controller.admin.character.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import cn.idev.excel.annotation.*; + +@Schema(description = "管理后台 - 键盘人设 Response VO") +@Data +@ExcelIgnoreUnannotated +public class KeyboardCharacterRespVO { + + @Schema(description = "主键 Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7592") + @ExcelProperty("主键 Id") + private Long id; + + @Schema(description = "标题", example = "王五") + @ExcelProperty("标题") + private String characterName; + + @Schema(description = "背景描述") + @ExcelProperty("背景描述") + private String characterBackground; + + @Schema(description = "角色头像", example = "https://www.iocoder.cn") + @ExcelProperty("角色头像") + private String avatarUrl; + + @Schema(description = "下载次数") + @ExcelProperty("下载次数") + private String download; + + @Schema(description = "标签id") + @ExcelProperty("标签id") + private Long tag; + + @Schema(description = "创建时间") + @ExcelProperty("创建时间") + private LocalDateTime createdAt; + + @Schema(description = "更新时间") + @ExcelProperty("更新时间") + private LocalDateTime updatedAt; + + @Schema(description = "人设提示词") + @ExcelProperty("人设提示词") + private String prompt; + + @Schema(description = "排名顺序") + @ExcelProperty("排名顺序") + private Integer rank; + + @Schema(description = "emoji 标签") + @ExcelProperty("emoji 标签") + private String emoji; + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterSaveReqVO.java b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterSaveReqVO.java new file mode 100644 index 0000000..60d765e --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/controller/admin/character/vo/KeyboardCharacterSaveReqVO.java @@ -0,0 +1,47 @@ +package com.yolo.keyboard.controller.admin.character.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import jakarta.validation.constraints.*; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 键盘人设新增/修改 Request VO") +@Data +public class KeyboardCharacterSaveReqVO { + + @Schema(description = "主键 Id", requiredMode = Schema.RequiredMode.REQUIRED, example = "7592") + private Long id; + + @Schema(description = "标题", example = "王五") + private String characterName; + + @Schema(description = "背景描述") + private String characterBackground; + + @Schema(description = "角色头像", example = "https://www.iocoder.cn") + private String avatarUrl; + + @Schema(description = "下载次数") + private String download; + + @Schema(description = "标签id") + private Long tag; + + @Schema(description = "创建时间") + private LocalDateTime createdAt; + + @Schema(description = "更新时间") + private LocalDateTime updatedAt; + + @Schema(description = "人设提示词") + private String prompt; + + @Schema(description = "排名顺序") + private Integer rank; + + @Schema(description = "emoji 标签") + private String emoji; + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/character/KeyboardCharacterDO.java b/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/character/KeyboardCharacterDO.java new file mode 100644 index 0000000..a7150b3 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/dal/dataobject/character/KeyboardCharacterDO.java @@ -0,0 +1,73 @@ +package com.yolo.keyboard.dal.dataobject.character; + +import com.yolo.keyboard.framework.tenant.core.aop.TenantIgnore; +import lombok.*; +import java.util.*; +import java.time.LocalDateTime; +import java.time.LocalDateTime; +import com.baomidou.mybatisplus.annotation.*; +import com.yolo.keyboard.framework.mybatis.core.dataobject.BaseDO; + +/** + * 键盘人设 DO + * + * @author ziin + */ +@TableName("keyboard_character") +@KeySequence("keyboard_character_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +@TenantIgnore +public class KeyboardCharacterDO { + + /** + * 主键 Id + */ + @TableId + private Long id; + /** + * 标题 + */ + private String characterName; + /** + * 背景描述 + */ + private String characterBackground; + /** + * 角色头像 + */ + private String avatarUrl; + /** + * 下载次数 + */ + private String download; + /** + * 标签id + */ + private Long tag; + /** + * 创建时间 + */ + private LocalDateTime createdAt; + /** + * 更新时间 + */ + private LocalDateTime updatedAt; + /** + * 人设提示词 + */ + private String prompt; + /** + * 排名顺序 + */ + private Integer rank; + /** + * emoji 标签 + */ + private String emoji; + + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/character/KeyboardCharacterMapper.java b/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/character/KeyboardCharacterMapper.java new file mode 100644 index 0000000..75ddfa7 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/dal/mysql/character/KeyboardCharacterMapper.java @@ -0,0 +1,35 @@ +package com.yolo.keyboard.dal.mysql.character; + +import java.util.*; + +import com.yolo.keyboard.framework.common.pojo.PageResult; +import com.yolo.keyboard.framework.mybatis.core.query.LambdaQueryWrapperX; +import com.yolo.keyboard.framework.mybatis.core.mapper.BaseMapperX; +import com.yolo.keyboard.dal.dataobject.character.KeyboardCharacterDO; +import org.apache.ibatis.annotations.Mapper; +import com.yolo.keyboard.controller.admin.character.vo.*; + +/** + * 键盘人设 Mapper + * + * @author ziin + */ +@Mapper +public interface KeyboardCharacterMapper extends BaseMapperX { + + default PageResult selectPage(KeyboardCharacterPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(KeyboardCharacterDO::getCharacterName, reqVO.getCharacterName()) + .eqIfPresent(KeyboardCharacterDO::getCharacterBackground, reqVO.getCharacterBackground()) + .eqIfPresent(KeyboardCharacterDO::getAvatarUrl, reqVO.getAvatarUrl()) + .eqIfPresent(KeyboardCharacterDO::getDownload, reqVO.getDownload()) + .eqIfPresent(KeyboardCharacterDO::getTag, reqVO.getTag()) + .eqIfPresent(KeyboardCharacterDO::getCreatedAt, reqVO.getCreatedAt()) + .eqIfPresent(KeyboardCharacterDO::getUpdatedAt, reqVO.getUpdatedAt()) + .eqIfPresent(KeyboardCharacterDO::getPrompt, reqVO.getPrompt()) + .eqIfPresent(KeyboardCharacterDO::getRank, reqVO.getRank()) + .eqIfPresent(KeyboardCharacterDO::getEmoji, reqVO.getEmoji()) + .orderByDesc(KeyboardCharacterDO::getId)); + } + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterService.java b/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterService.java new file mode 100644 index 0000000..65beeb6 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterService.java @@ -0,0 +1,61 @@ +package com.yolo.keyboard.service.character; + +import java.util.*; +import jakarta.validation.*; +import com.yolo.keyboard.controller.admin.character.vo.*; +import com.yolo.keyboard.dal.dataobject.character.KeyboardCharacterDO; +import com.yolo.keyboard.framework.common.pojo.PageResult; + +/** + * 键盘人设 Service 接口 + * + * @author ziin + */ +public interface KeyboardCharacterService { + + /** + * 创建键盘人设 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createCharacter(@Valid KeyboardCharacterSaveReqVO createReqVO); + + /** + * 更新键盘人设 + * + * @param updateReqVO 更新信息 + */ + void updateCharacter(@Valid KeyboardCharacterSaveReqVO updateReqVO); + + /** + * 删除键盘人设 + * + * @param id 编号 + */ + void deleteCharacter(Long id); + + /** + * 批量删除键盘人设 + * + * @param ids 编号 + */ + void deleteCharacterListByIds(List ids); + + /** + * 获得键盘人设 + * + * @param id 编号 + * @return 键盘人设 + */ + KeyboardCharacterDO getCharacter(Long id); + + /** + * 获得键盘人设分页 + * + * @param pageReqVO 分页查询 + * @return 键盘人设分页 + */ + PageResult getCharacterPage(KeyboardCharacterPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterServiceImpl.java b/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterServiceImpl.java new file mode 100644 index 0000000..155e5a4 --- /dev/null +++ b/keyboard-server/src/main/java/com/yolo/keyboard/service/character/KeyboardCharacterServiceImpl.java @@ -0,0 +1,81 @@ +package com.yolo.keyboard.service.character; + +import org.springframework.stereotype.Service; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; + +import java.util.*; +import com.yolo.keyboard.controller.admin.character.vo.*; +import com.yolo.keyboard.dal.dataobject.character.KeyboardCharacterDO; +import com.yolo.keyboard.framework.common.pojo.PageResult; +import com.yolo.keyboard.framework.common.util.object.BeanUtils; + +import com.yolo.keyboard.dal.mysql.character.KeyboardCharacterMapper; + +import static com.yolo.keyboard.framework.common.exception.util.ServiceExceptionUtil.exception; +import static com.yolo.keyboard.module.infra.enums.ErrorCodeConstants.CHARACTER_NOT_EXISTS; + + +/** + * 键盘人设 Service 实现类 + * + * @author ziin + */ +@Service +@Validated +public class KeyboardCharacterServiceImpl implements KeyboardCharacterService { + + @Resource + private KeyboardCharacterMapper characterMapper; + + @Override + public Long createCharacter(KeyboardCharacterSaveReqVO createReqVO) { + // 插入 + KeyboardCharacterDO character = BeanUtils.toBean(createReqVO, KeyboardCharacterDO.class); + characterMapper.insert(character); + + // 返回 + return character.getId(); + } + + @Override + public void updateCharacter(KeyboardCharacterSaveReqVO updateReqVO) { + // 校验存在 + validateCharacterExists(updateReqVO.getId()); + // 更新 + KeyboardCharacterDO updateObj = BeanUtils.toBean(updateReqVO, KeyboardCharacterDO.class); + characterMapper.updateById(updateObj); + } + + @Override + public void deleteCharacter(Long id) { + // 校验存在 + validateCharacterExists(id); + // 删除 + characterMapper.deleteById(id); + } + + @Override + public void deleteCharacterListByIds(List ids) { + // 删除 + characterMapper.deleteByIds(ids); + } + + + private void validateCharacterExists(Long id) { + if (characterMapper.selectById(id) == null) { + throw exception(CHARACTER_NOT_EXISTS); + } + } + + @Override + public KeyboardCharacterDO getCharacter(Long id) { + return characterMapper.selectById(id); + } + + @Override + public PageResult getCharacterPage(KeyboardCharacterPageReqVO pageReqVO) { + return characterMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/keyboard-server/src/main/resources/mapper/character/KeyboardCharacterMapper.xml b/keyboard-server/src/main/resources/mapper/character/KeyboardCharacterMapper.xml new file mode 100644 index 0000000..e652eb7 --- /dev/null +++ b/keyboard-server/src/main/resources/mapper/character/KeyboardCharacterMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yolo-module-infra/src/main/java/com/yolo/keyboard/module/infra/enums/ErrorCodeConstants.java b/yolo-module-infra/src/main/java/com/yolo/keyboard/module/infra/enums/ErrorCodeConstants.java index 786620b..4f3355e 100644 --- a/yolo-module-infra/src/main/java/com/yolo/keyboard/module/infra/enums/ErrorCodeConstants.java +++ b/yolo-module-infra/src/main/java/com/yolo/keyboard/module/infra/enums/ErrorCodeConstants.java @@ -75,5 +75,6 @@ public interface ErrorCodeConstants { ErrorCode THEMES_NOT_EXISTS = new ErrorCode(1_001_202_001, "键盘皮肤不存在"); ErrorCode KEYBOARD_THEME_STYLES_NOT_EXISTS = new ErrorCode(1_001_202_002, "主题风格不存在"); ErrorCode THEME_PURCHASE_NOT_EXISTS = new ErrorCode(1_001_202_003, "皮肤购买记录表(积分支付)不存在"); + ErrorCode CHARACTER_NOT_EXISTS = new ErrorCode(1_001_202_004, "键盘人设不存在"); }