feat: 功能

This commit is contained in:
2025-11-12 22:45:29 +08:00
parent 94c114a44d
commit fc7d2ccea5
41 changed files with 2406 additions and 343 deletions

View File

@@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.ai.dal.dataobject.userprompt;
import lombok.*;
import java.util.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
/**
* 用户提示词 DO
*
* @author 芋道源码
*/
@TableName("ai_user_prompt")
@KeySequence("ai_user_prompt_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserPromptDO extends TenantBaseDO {
/**
* 编号
*/
@TableId
private Long id;
/**
* 用户编号
*/
private Long userId;
/**
* 提示词名称
*/
private String name;
/**
* 提示词内容
*/
private String content;
/**
* 分类/标签
*/
private String category;
/**
* 是否公开0-私有1-公开)
*/
private Boolean isPublic;
/**
* 排序
*/
private Integer sort;
/**
* 使用次数
*/
private Integer useCount;
/**
* 状态0-禁用1-启用)
*/
private Integer status;
/**
* 备注
*/
private String remark;
}

View File

@@ -60,9 +60,9 @@ public interface ErrorCodeConstants {
// ========== AI 工具 1-040-010-000 ==========
ErrorCode TOOL_NOT_EXISTS = new ErrorCode(1_040_010_000, "工具不存在");
ErrorCode TOOL_NAME_NOT_EXISTS = new ErrorCode(1_040_010_001, "工具({})找不到 Bean");
ErrorCode USER_PROMPT_NOT_EXISTS = new ErrorCode(1_040_010_002, "用户提示词不存在");
// ========== AI 工作流 1-040-011-000 ==========
ErrorCode WORKFLOW_NOT_EXISTS = new ErrorCode(1_040_011_000, "工作流不存在");
ErrorCode WORKFLOW_CODE_EXISTS = new ErrorCode(1_040_011_001, "工作流标识已存在");
}

View File

@@ -0,0 +1,104 @@
package cn.iocoder.yudao.module.ai.userprompt.controller;
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 cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.ai.userprompt.vo.*;
import cn.iocoder.yudao.module.ai.dal.dataobject.userprompt.UserPromptDO;
import cn.iocoder.yudao.module.ai.userprompt.service.UserPromptService;
@Tag(name = "AI - 用户提示词")
@RestController
@RequestMapping("/ai/user-prompt")
@Validated
public class UserPromptController {
@Resource
private UserPromptService userPromptService;
@PostMapping("/create")
@Operation(summary = "创建用户提示词")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:create')")
public CommonResult<Long> createUserPrompt(@Valid @RequestBody UserPromptSaveReqVO createReqVO) {
return success(userPromptService.createUserPrompt(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户提示词")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:update')")
public CommonResult<Boolean> updateUserPrompt(@Valid @RequestBody UserPromptSaveReqVO updateReqVO) {
userPromptService.updateUserPrompt(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户提示词")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ai:user-prompt:delete')")
public CommonResult<Boolean> deleteUserPrompt(@RequestParam("id") Long id) {
userPromptService.deleteUserPrompt(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除用户提示词")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:delete')")
public CommonResult<Boolean> deleteUserPromptList(@RequestParam("ids") List<Long> ids) {
userPromptService.deleteUserPromptListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户提示词")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:query')")
public CommonResult<UserPromptRespVO> getUserPrompt(@RequestParam("id") Long id) {
UserPromptDO userPrompt = userPromptService.getUserPrompt(id);
return success(BeanUtils.toBean(userPrompt, UserPromptRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得用户提示词分页")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:query')")
public CommonResult<PageResult<UserPromptRespVO>> getUserPromptPage(@Valid UserPromptPageReqVO pageReqVO) {
PageResult<UserPromptDO> pageResult = userPromptService.getUserPromptPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, UserPromptRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出用户提示词 Excel")
@PreAuthorize("@ss.hasPermission('ai:user-prompt:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportUserPromptExcel(@Valid UserPromptPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<UserPromptDO> list = userPromptService.getUserPromptPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "用户提示词.xls", "数据", UserPromptRespVO.class,
BeanUtils.toBean(list, UserPromptRespVO.class));
}
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.ai.userprompt.mapper;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.ai.dal.dataobject.userprompt.UserPromptDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.ai.userprompt.vo.*;
/**
* 用户提示词 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface UserPromptMapper extends BaseMapperX<UserPromptDO> {
default PageResult<UserPromptDO> selectPage(UserPromptPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<UserPromptDO>()
.eqIfPresent(UserPromptDO::getUserId, reqVO.getUserId())
.likeIfPresent(UserPromptDO::getName, reqVO.getName())
.eqIfPresent(UserPromptDO::getContent, reqVO.getContent())
.eqIfPresent(UserPromptDO::getCategory, reqVO.getCategory())
.eqIfPresent(UserPromptDO::getIsPublic, reqVO.getIsPublic())
.eqIfPresent(UserPromptDO::getSort, reqVO.getSort())
.eqIfPresent(UserPromptDO::getUseCount, reqVO.getUseCount())
.eqIfPresent(UserPromptDO::getStatus, reqVO.getStatus())
.eqIfPresent(UserPromptDO::getRemark, reqVO.getRemark())
.betweenIfPresent(UserPromptDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(UserPromptDO::getId));
}
}

View File

@@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.ai.userprompt.service;
import java.util.*;
import jakarta.validation.*;
import cn.iocoder.yudao.module.ai.userprompt.vo.*;
import cn.iocoder.yudao.module.ai.dal.dataobject.userprompt.UserPromptDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
/**
* 用户提示词 Service 接口
*
* @author 芋道源码
*/
public interface UserPromptService {
/**
* 创建用户提示词
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createUserPrompt(@Valid UserPromptSaveReqVO createReqVO);
/**
* 更新用户提示词
*
* @param updateReqVO 更新信息
*/
void updateUserPrompt(@Valid UserPromptSaveReqVO updateReqVO);
/**
* 删除用户提示词
*
* @param id 编号
*/
void deleteUserPrompt(Long id);
/**
* 批量删除用户提示词
*
* @param ids 编号
*/
void deleteUserPromptListByIds(List<Long> ids);
/**
* 获得用户提示词
*
* @param id 编号
* @return 用户提示词
*/
UserPromptDO getUserPrompt(Long id);
/**
* 获得用户提示词分页
*
* @param pageReqVO 分页查询
* @return 用户提示词分页
*/
PageResult<UserPromptDO> getUserPromptPage(UserPromptPageReqVO pageReqVO);
}

View File

@@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.ai.userprompt.service;
import cn.hutool.core.collection.CollUtil;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.module.ai.userprompt.vo.*;
import cn.iocoder.yudao.module.ai.dal.dataobject.userprompt.UserPromptDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ai.userprompt.mapper.UserPromptMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.*;
/**
* 用户提示词 Service 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class UserPromptServiceImpl implements UserPromptService {
@Resource
private UserPromptMapper userPromptMapper;
@Override
public Long createUserPrompt(UserPromptSaveReqVO createReqVO) {
// 插入
UserPromptDO userPrompt = BeanUtils.toBean(createReqVO, UserPromptDO.class);
userPromptMapper.insert(userPrompt);
// 返回
return userPrompt.getId();
}
@Override
public void updateUserPrompt(UserPromptSaveReqVO updateReqVO) {
// 校验存在
validateUserPromptExists(updateReqVO.getId());
// 更新
UserPromptDO updateObj = BeanUtils.toBean(updateReqVO, UserPromptDO.class);
userPromptMapper.updateById(updateObj);
}
@Override
public void deleteUserPrompt(Long id) {
// 校验存在
validateUserPromptExists(id);
// 删除
userPromptMapper.deleteById(id);
}
@Override
public void deleteUserPromptListByIds(List<Long> ids) {
// 删除
userPromptMapper.deleteByIds(ids);
}
private void validateUserPromptExists(Long id) {
if (userPromptMapper.selectById(id) == null) {
throw exception(USER_PROMPT_NOT_EXISTS);
}
}
@Override
public UserPromptDO getUserPrompt(Long id) {
return userPromptMapper.selectById(id);
}
@Override
public PageResult<UserPromptDO> getUserPromptPage(UserPromptPageReqVO pageReqVO) {
return userPromptMapper.selectPage(pageReqVO);
}
}

View File

@@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.ai.userprompt.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 用户提示词分页 Request VO")
@Data
public class UserPromptPageReqVO extends PageParam {
@Schema(description = "用户编号", example = "12926")
private Long userId;
@Schema(description = "提示词名称", example = "张三")
private String name;
@Schema(description = "提示词内容")
private String content;
@Schema(description = "分类/标签")
private String category;
@Schema(description = "是否公开0-私有1-公开)")
private Boolean isPublic;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "使用次数", example = "22185")
private Integer useCount;
@Schema(description = "状态0-禁用1-启用)", example = "1")
private Integer status;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.ai.userprompt.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 UserPromptRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12482")
@ExcelProperty("编号")
private Long id;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12926")
@ExcelProperty("用户编号")
private Long userId;
@Schema(description = "提示词名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@ExcelProperty("提示词名称")
private String name;
@Schema(description = "提示词内容", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("提示词内容")
private String content;
@Schema(description = "分类/标签")
@ExcelProperty("分类/标签")
private String category;
@Schema(description = "是否公开0-私有1-公开)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否公开0-私有1-公开)")
private Boolean isPublic;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("排序")
private Integer sort;
@Schema(description = "使用次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "22185")
@ExcelProperty("使用次数")
private Integer useCount;
@Schema(description = "状态0-禁用1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("状态0-禁用1-启用)")
private Integer status;
@Schema(description = "备注", example = "你说的对")
@ExcelProperty("备注")
private String remark;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@@ -0,0 +1,49 @@
package cn.iocoder.yudao.module.ai.userprompt.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - 用户提示词新增/修改 Request VO")
@Data
public class UserPromptSaveReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12482")
private Long id;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12926")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "提示词名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@NotEmpty(message = "提示词名称不能为空")
private String name;
@Schema(description = "提示词内容", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "提示词内容不能为空")
private String content;
@Schema(description = "分类/标签")
private String category;
@Schema(description = "是否公开0-私有1-公开)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "是否公开0-私有1-公开)不能为空")
private Boolean isPublic;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "使用次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "22185")
@NotNull(message = "使用次数不能为空")
private Integer useCount;
@Schema(description = "状态0-禁用1-启用)", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态0-禁用1-启用)不能为空")
private Integer status;
@Schema(description = "备注", example = "你说的对")
private String remark;
}