From 0f1fc16f985e6c206dc4504638473abfe0793114 Mon Sep 17 00:00:00 2001 From: xs Date: Fri, 12 Sep 2025 16:51:26 +0800 Subject: [PATCH] =?UTF-8?q?1.5.4=E5=90=8E=E7=AB=AF=20AI=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AiFormSettingController.java | 154 +++++++++ .../org/dromara/ai/domain/AiFormSetting.java | 96 ++++++ .../ai/domain/AiFormSettingDetail.java | 61 ++++ .../dromara/ai/domain/bo/AiFormSettingBo.java | 95 ++++++ .../ai/domain/bo/AiFormSettingDetailBo.java | 66 ++++ .../ai/domain/vo/AiFormSettingDetailVo.java | 76 +++++ .../dromara/ai/domain/vo/AiFormSettingVo.java | 106 ++++++ .../ai/mapper/AiFormSettingDetailMapper.java | 19 ++ .../ai/mapper/AiFormSettingMapper.java | 28 ++ .../ai/service/IAiFormSettingService.java | 90 +++++ .../impl/AiFormSettingServiceImpl.java | 318 ++++++++++++++++++ .../mapper/ai/AiFormSettingDetailMapper.xml | 14 + .../mapper/ai/AiFormSettingMapper.xml | 10 + 13 files changed, 1133 insertions(+) create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/controller/AiFormSettingController.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSetting.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSettingDetail.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingBo.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingDetailBo.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingDetailVo.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingVo.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingDetailMapper.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingMapper.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/IAiFormSettingService.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/impl/AiFormSettingServiceImpl.java create mode 100644 ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingDetailMapper.xml create mode 100644 ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingMapper.xml diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/controller/AiFormSettingController.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/controller/AiFormSettingController.java new file mode 100644 index 00000000..6d44ef58 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/controller/AiFormSettingController.java @@ -0,0 +1,154 @@ +package org.dromara.ai.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.ai.domain.AiFormSetting; +import org.dromara.ai.domain.AiSqlTable; +import org.dromara.ai.domain.bo.AiSqlTableBo; +import org.dromara.ai.domain.vo.AiFormSettingDetailVo; +import org.dromara.common.mybatis.helper.DataBaseHelper; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.ai.domain.vo.AiFormSettingVo; +import org.dromara.ai.domain.bo.AiFormSettingBo; +import org.dromara.ai.service.IAiFormSettingService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * AI表单设置 + * 前端访问路由地址为:/ai/aiFormSetting + * + * @author xins + * @date 2025-09-10 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/aiFormSetting") +public class AiFormSettingController extends BaseController { + + private final IAiFormSettingService aiFormSettingService; + + /** + * 查询AI表单设置列表 + */ + @SaCheckPermission("ai:aiFormSetting:list") + @GetMapping("/list") + public TableDataInfo list(AiFormSettingBo bo, PageQuery pageQuery) { + return aiFormSettingService.queryPageList(bo, pageQuery); + } + + /** + * 导出AI表单设置列表 + */ + @SaCheckPermission("ai:aiFormSetting:export") + @Log(title = "AI表单设置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(AiFormSettingBo bo, HttpServletResponse response) { + List list = aiFormSettingService.queryList(bo); + ExcelUtil.exportExcel(list, "AI表单设置", AiFormSettingVo.class, response); + } + + /** + * 获取AI表单设置详细信息 + * + * @param formSettingId 主键 + */ + @SaCheckPermission("ai:aiFormSetting:query") + @GetMapping("/{formSettingId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long formSettingId) { + return R.ok(aiFormSettingService.queryById(formSettingId)); + } + + /** + * 新增AI表单设置 + */ + @SaCheckPermission("ai:aiFormSetting:add") + @Log(title = "AI表单设置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody AiFormSettingBo bo) { + return toAjax(aiFormSettingService.insertByBo(bo)); + } + + /** + * 修改AI表单设置 + */ + @SaCheckPermission("ai:aiFormSetting:edit") + @Log(title = "AI表单设置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody AiFormSettingBo bo) { + return toAjax(aiFormSettingService.updateByBo(bo)); + } + + /** + * 删除AI表单设置 + * + * @param formSettingIds 主键串 + */ + @SaCheckPermission("ai:aiFormSetting:remove") + @Log(title = "AI表单设置", businessType = BusinessType.DELETE) + @DeleteMapping("/{formSettingIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] formSettingIds) { + return toAjax(aiFormSettingService.deleteWithValidByIds(List.of(formSettingIds), true)); + } + + + /** + * 下拉框查询AI表单设置列表 + */ + + @GetMapping("/getAiFormSettingList") + public R> getAiFormSettingList(AiFormSettingBo bo) { + List list = aiFormSettingService.queryList(bo); + return R.ok(list); + } + + + /** + * 查询数据源名称列表 + */ + @SaCheckPermission("ai:aiFormSetting:list") + @GetMapping(value = "/getDataNames") + public R getCurrentDataSourceNameList() { + return R.ok(DataBaseHelper.getDataSourceNameList()); + } + + /** + * 查询数据库列表 + */ + @SaCheckPermission("ai:aiFormSetting:list") + @GetMapping("/db/list") + public TableDataInfo dbTableList(AiFormSettingBo aiFormSettingBo, PageQuery pageQuery) { + return aiFormSettingService.selectPageDbTableList(aiFormSettingBo, pageQuery); + } + + + /** + * 查询数据库表Column列表 + */ + @SaCheckPermission("ai:aiFormSetting:list") + @GetMapping("/db/columnList") + public R> dbTableColumnList(AiFormSettingBo aiFormSettingBo) { + return R.ok(aiFormSettingService.selectDbTableColumnsByName(aiFormSettingBo.getTableName(), + aiFormSettingBo.getDataName())); + } + + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSetting.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSetting.java new file mode 100644 index 00000000..3d3cba60 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSetting.java @@ -0,0 +1,96 @@ +package org.dromara.ai.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.util.List; + +/** + * AI表单设置对象 ai_form_setting + * + * @author xins + * @date 2025-09-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("ai_form_setting") +public class AiFormSetting extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "form_setting_id", type = IdType.AUTO) + private Long formSettingId; + + /** + * 表单类型(1单表,2主子表,3主form子table) + */ + private String formType; + + + /** + * 数据源名称 + */ + private String dataName; + + /** + * 表名称 + */ + private String tableName; + + /** + * 表注释 + */ + private String tableComment; + + /** + * 表单名称 + */ + private String formName; + + /** + * 表单路径(与sys_menu中的component一样,例如/mes/info/index) + */ + private String formPath; + + /** + * 弹窗可见变量名称 + */ + private String dialogVisibleVariable; + + /** + * 子表名称 + */ + private String subTableName; + + /** + * 子表关联的外键名 + */ + private String subTableFkName; + + /** + * 客户端类型(1Web,2手机) + */ + private String clientType; + + /** + * 备注 + */ + private String remark; + + /** + * 删除标志(0代表存在 2代表删除),暂时不用 + */ +// @TableLogic + private String delFlag; + + + @TableField(exist = false) + private List aiFormSettingDetailList; +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSettingDetail.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSettingDetail.java new file mode 100644 index 00000000..229a235b --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/AiFormSettingDetail.java @@ -0,0 +1,61 @@ +package org.dromara.ai.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * AI表单设置详情对象 ai_form_setting_detail + * + * @author xins + * @date 2025-09-10 + */ +@Data +//@EqualsAndHashCode(callSuper = true) +@TableName("ai_form_setting_detail") +public class AiFormSettingDetail { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "setting_detail_id", type = IdType.AUTO) + private Long settingDetailId; + + /** + * AI表单设置ID,关联ai_form_setting + */ + private Long formSettingId; + + /** + * 表名称(用于一个表单多个表的情况) + */ + private String tableName; + + /** + * 字段名称 + */ + private String fieldName; + + /** + * 字段描述(如果有关联表,则在此说明,例如关联表sys_dept,sys_dept中字段dept_name是部门名称) + */ + private String fieldDesc; + + /** + * 表单prop + */ + private String formProp; + + /** + * 设置标识(1是,0否),代表是否需要AI赋值 + */ + private String settingFlag; + + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingBo.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingBo.java new file mode 100644 index 00000000..2dabc74a --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingBo.java @@ -0,0 +1,95 @@ +package org.dromara.ai.domain.bo; + +import org.dromara.ai.domain.AiFormSetting; +import org.dromara.ai.domain.AiFormSettingDetail; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +import java.util.List; + +/** + * AI表单设置业务对象 ai_form_setting + * + * @author xins + * @date 2025-09-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = AiFormSetting.class, reverseConvertGenerate = false) +public class AiFormSettingBo extends BaseEntity { + + /** + * 主键 + */ + private Long formSettingId; + + /** + * 表单类型(1单表,2主子表,3主form子table)1 + */ + @NotBlank(message = "表单类型(1单表,2主子表,3主form子table)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String formType; + + /** + * 数据源名称 + */ + @NotBlank(message = "数据源名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String dataName; + + /** + * 表名称 + */ + @NotBlank(message = "表名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String tableName; + + /** + * 表注释 + */ + private String tableComment; + + /** + * 表单名称 + */ + @NotBlank(message = "表单名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String formName; + + /** + * 表单路径(与sys_menu中的component一样,例如/mes/info/index) + */ + @NotBlank(message = "表单路径不能为空", groups = { AddGroup.class, EditGroup.class }) + private String formPath; + + /** + * 弹窗可见变量名称 + */ + private String dialogVisibleVariable; + + /** + * 子表名称 + */ + private String subTableName; + + /** + * 子表关联的外键名 + */ + private String subTableFkName; + + /** + * 客户端类型(1Web,2手机) + */ + @NotBlank(message = "客户端类型不能为空", groups = { AddGroup.class, EditGroup.class }) + private String clientType; + + /** + * 备注 + */ + private String remark; + + + private List aiFormSettingDetailList; + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingDetailBo.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingDetailBo.java new file mode 100644 index 00000000..dcc98c36 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/bo/AiFormSettingDetailBo.java @@ -0,0 +1,66 @@ +package org.dromara.ai.domain.bo; + +import org.dromara.ai.domain.AiFormSettingDetail; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * AI表单设置详情业务对象 ai_form_setting_detail + * + * @author xins + * @date 2025-09-10 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = AiFormSettingDetail.class, reverseConvertGenerate = false) +public class AiFormSettingDetailBo extends BaseEntity { + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long settingDetailId; + + /** + * AI表单设置ID,关联ai_form_setting + */ + @NotNull(message = "AI表单设置ID,关联ai_form_setting不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long formSettingId; + + /** + * 表名称(用于一个表单多个表的情况) + */ + @NotBlank(message = "表名称(用于一个表单多个表的情况)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String tableName; + + /** + * 字段名称 + */ + @NotBlank(message = "字段名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String fieldName; + + /** + * 字段描述(如果有关联表,则在此说明,例如关联表sys_dept,sys_dept中字段dept_name是部门名称) + */ + @NotBlank(message = "字段描述(如果有关联表,则在此说明,例如关联表sys_dept,sys_dept中字段dept_name是部门名称)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String fieldDesc; + + /** + * 表单prop + */ + @NotBlank(message = "表单prop不能为空", groups = { AddGroup.class, EditGroup.class }) + private String formProp; + + /** + * 设置标识(1是,0否),代表是否需要AI赋值 + */ + @NotBlank(message = "设置标识(1是,0否),代表是否需要AI赋值不能为空", groups = { AddGroup.class, EditGroup.class }) + private String settingFlag; + + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingDetailVo.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingDetailVo.java new file mode 100644 index 00000000..36f95a43 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingDetailVo.java @@ -0,0 +1,76 @@ +package org.dromara.ai.domain.vo; + +import org.dromara.ai.domain.AiFormSettingDetail; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * AI表单设置详情视图对象 ai_form_setting_detail + * + * @author xins + * @date 2025-09-10 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = AiFormSettingDetail.class) +public class AiFormSettingDetailVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long settingDetailId; + + /** + * AI表单设置ID,关联ai_form_setting + */ + @ExcelProperty(value = "AI表单设置ID,关联ai_form_setting") + private Long formSettingId; + + /** + * 表名称(用于一个表单多个表的情况) + */ + @ExcelProperty(value = "表名称", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "用=于一个表单多个表的情况") + private String tableName; + + /** + * 字段名称 + */ + @ExcelProperty(value = "字段名称") + private String fieldName; + + /** + * 字段描述(如果有关联表,则在此说明,例如关联表sys_dept,sys_dept中字段dept_name是部门名称) + */ + @ExcelProperty(value = "字段描述", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "如=果有关联表,则在此说明,例如关联表sys_dept,sys_dept中字段dept_name是部门名称") + private String fieldDesc; + + /** + * 表单prop + */ + @ExcelProperty(value = "表单prop") + private String formProp; + + /** + * 设置标识(1是,0否),代表是否需要AI赋值 + */ + @ExcelProperty(value = "设置标识(1是,0否),代表是否需要AI赋值") + private String settingFlag; + + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingVo.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingVo.java new file mode 100644 index 00000000..400d181b --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/domain/vo/AiFormSettingVo.java @@ -0,0 +1,106 @@ +package org.dromara.ai.domain.vo; + +import org.dromara.ai.domain.AiFormSetting; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.ai.domain.AiFormSettingDetail; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; +import java.util.List; + + +/** + * AI表单设置视图对象 ai_form_setting + * + * @author xins + * @date 2025-09-10 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = AiFormSetting.class) +public class AiFormSettingVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long formSettingId; + + /** + * 表单类型(1单表,2主子表,3主form子table) + */ + @ExcelProperty(value = "表单类型(1单表,2主子表,3主form子table)") + private String formType; + + /** + * 数据源名称 + */ + @ExcelProperty(value = "数据源名称") + private String dataName; + + /** + * 表名称 + */ + @ExcelProperty(value = "表名称") + private String tableName; + + /** + * 表注释 + */ + @ExcelProperty(value = "表注释") + private String tableComment; + + /** + * 表单名称 + */ + @ExcelProperty(value = "表单名称") + private String formName; + + /** + * 表单路径(与sys_menu中的component一样,例如/mes/info/index) + */ + @ExcelProperty(value = "表单路径(与sys_menu中的component一样,例如/mes/info/index)") + private String formPath; + + /** + * 弹窗可见变量名称 + */ + @ExcelProperty(value = "弹窗可见变量名称") + private String dialogVisibleVariable; + + /** + * 子表名称 + */ + @ExcelProperty(value = "子表名称") + private String subTableName; + + /** + * 子表关联的外键名 + */ + @ExcelProperty(value = "子表关联的外键名") + private String subTableFkName; + + /** + * 客户端类型(1Web,2手机) + */ + @ExcelProperty(value = "客户端类型(1Web,2手机)") + private String clientType; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + private List aiFormSettingDetailList; + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingDetailMapper.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingDetailMapper.java new file mode 100644 index 00000000..f640ac00 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingDetailMapper.java @@ -0,0 +1,19 @@ +package org.dromara.ai.mapper; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import org.dromara.ai.domain.AiFormSettingDetail; +import org.dromara.ai.domain.vo.AiFormSettingDetailVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +import java.util.List; + +/** + * AI表单设置详情Mapper接口 + * + * @author xins + * @date 2025-09-10 + */ +public interface AiFormSettingDetailMapper extends BaseMapperPlus { + + public int insertFormSettingDetailBatch(List list); +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingMapper.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingMapper.java new file mode 100644 index 00000000..7459525e --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/mapper/AiFormSettingMapper.java @@ -0,0 +1,28 @@ +package org.dromara.ai.mapper; + +import com.baomidou.dynamic.datasource.annotation.DS; +import org.dromara.ai.domain.AiFormSetting; +import org.dromara.ai.domain.vo.AiFormSettingVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +import java.util.List; + +/** + * AI表单设置Mapper接口 + * + * @author xins + * @date 2025-09-10 + */ +public interface AiFormSettingMapper extends BaseMapperPlus { + + /** + * 查询指定数据源下的所有表名列表 + * + * @param dataName 数据源名称,用于选择不同的数据源 + * @return 当前数据库中的表名列表 + * + * @DS("") 使用默认数据源执行查询操作 + */ + @DS("") + List selectTableNameList(String dataName); +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/IAiFormSettingService.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/IAiFormSettingService.java new file mode 100644 index 00000000..87e5d048 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/IAiFormSettingService.java @@ -0,0 +1,90 @@ +package org.dromara.ai.service; + +import com.baomidou.dynamic.datasource.annotation.DS; +import org.dromara.ai.domain.AiFormSetting; +import org.dromara.ai.domain.vo.AiFormSettingDetailVo; +import org.dromara.ai.domain.vo.AiFormSettingVo; +import org.dromara.ai.domain.bo.AiFormSettingBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * AI表单设置Service接口 + * + * @author xins + * @date 2025-09-10 + */ +public interface IAiFormSettingService { + + /** + * 查询AI表单设置 + * + * @param formSettingId 主键 + * @return AI表单设置 + */ + AiFormSettingVo queryById(Long formSettingId); + + /** + * 分页查询AI表单设置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return AI表单设置分页列表 + */ + TableDataInfo queryPageList(AiFormSettingBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的AI表单设置列表 + * + * @param bo 查询条件 + * @return AI表单设置列表 + */ + List queryList(AiFormSettingBo bo); + + /** + * 新增AI表单设置 + * + * @param bo AI表单设置 + * @return 是否新增成功 + */ + Boolean insertByBo(AiFormSettingBo bo); + + /** + * 修改AI表单设置 + * + * @param bo AI表单设置 + * @return 是否修改成功 + */ + Boolean updateByBo(AiFormSettingBo bo); + + /** + * 校验并批量删除AI表单设置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 查询数据库列表 + * + * @param aiFormSettingBo AiFormSettingBo + * @param pageQuery 包含分页信息的PageQuery对象 + * @return 包含分页结果的TableDataInfo对象 + */ + public TableDataInfo selectPageDbTableList(AiFormSettingBo aiFormSettingBo, PageQuery pageQuery); + + + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @param dataName 数据源名称 + * @return 列信息 + */ + public List selectDbTableColumnsByName(String tableName, String dataName); +} diff --git a/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/impl/AiFormSettingServiceImpl.java b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/impl/AiFormSettingServiceImpl.java new file mode 100644 index 00000000..fbff103e --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/java/org/dromara/ai/service/impl/AiFormSettingServiceImpl.java @@ -0,0 +1,318 @@ +package org.dromara.ai.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.yulichang.interfaces.MPJBaseJoin; +import org.anyline.metadata.Column; +import org.anyline.metadata.Table; +import org.anyline.proxy.ServiceProxy; +import org.dromara.ai.domain.AiChatMessage; +import org.dromara.ai.domain.AiFormSettingDetail; +import org.dromara.ai.domain.vo.AiFormSettingDetailVo; +import org.dromara.ai.mapper.AiFormSettingDetailMapper; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.github.yulichang.toolkit.JoinWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.dromara.ai.domain.bo.AiFormSettingBo; +import org.dromara.ai.domain.vo.AiFormSettingVo; +import org.dromara.ai.domain.AiFormSetting; +import org.dromara.ai.mapper.AiFormSettingMapper; +import org.dromara.ai.service.IAiFormSettingService; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * AI表单设置Service业务层处理 + * + * @author xins + * @date 2025-09-10 + */ +@RequiredArgsConstructor +@Service +public class AiFormSettingServiceImpl implements IAiFormSettingService { + + private static final String[] TABLE_IGNORE = new String[]{"sj_", "act_", "flw_", "gen_"}; + + private final AiFormSettingMapper baseMapper; + + private final AiFormSettingDetailMapper aiFormSettingDetailMapper; + + /** + * 查询AI表单设置 + * + * @param formSettingId 主键 + * @return AI表单设置 + */ + @Override + public AiFormSettingVo queryById(Long formSettingId){ + MPJLambdaWrapper lqw = JoinWrappers.lambda(AiFormSettingDetail.class) + .select(AiFormSettingDetail::getSettingDetailId) + .select(AiFormSettingDetail::getFieldName) + .select(AiFormSettingDetail::getFieldDesc) + .select(AiFormSettingDetail::getFormProp) + .select(AiFormSettingDetail::getSettingFlag) + .eq(AiFormSettingDetail::getFormSettingId, formSettingId); + List aiFormSettingDetailList = aiFormSettingDetailMapper.selectList(lqw); + AiFormSettingVo aiFormSetting = baseMapper.selectVoById(formSettingId); + aiFormSetting.setAiFormSettingDetailList(aiFormSettingDetailList); + + return aiFormSetting; + } + + /** + * 分页查询AI表单设置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return AI表单设置分页列表 + */ + @Override + public TableDataInfo queryPageList(AiFormSettingBo bo, PageQuery pageQuery) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的AI表单设置列表 + * + * @param bo 查询条件 + * @return AI表单设置列表 + */ + @Override + public List queryList(AiFormSettingBo bo) { + MPJLambdaWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private MPJLambdaWrapper buildQueryWrapper(AiFormSettingBo bo) { + Map params = bo.getParams(); + MPJLambdaWrapper lqw = JoinWrappers.lambda(AiFormSetting.class) + .selectAll(AiFormSetting.class) + .eq(bo.getFormSettingId() != null, AiFormSetting::getFormSettingId, bo.getFormSettingId()) + .eq(StringUtils.isNotBlank(bo.getFormType()), AiFormSetting::getFormType, bo.getFormType()) + .like(StringUtils.isNotBlank(bo.getTableName()), AiFormSetting::getTableName, bo.getTableName()) + .like(StringUtils.isNotBlank(bo.getFormName()), AiFormSetting::getFormName, bo.getFormName()) + .like(StringUtils.isNotBlank(bo.getFormPath()), AiFormSetting::getFormPath, bo.getFormPath()) + .eq(StringUtils.isNotBlank(bo.getDialogVisibleVariable()), AiFormSetting::getDialogVisibleVariable, bo.getDialogVisibleVariable()) + .like(StringUtils.isNotBlank(bo.getSubTableName()), AiFormSetting::getSubTableName, bo.getSubTableName()) + .like(StringUtils.isNotBlank(bo.getSubTableFkName()), AiFormSetting::getSubTableFkName, bo.getSubTableFkName()) + .eq(StringUtils.isNotBlank(bo.getClientType()), AiFormSetting::getClientType, bo.getClientType()) + .orderByDesc(AiFormSetting::getCreateTime); + return lqw; + } + + /** + * 新增AI表单设置 + * + * @param bo AI表单设置 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(AiFormSettingBo bo) { + AiFormSetting add = MapstructUtils.convert(bo, AiFormSetting.class); + validEntityBeforeSave(add); + + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + List detailList = bo.getAiFormSettingDetailList(); + detailList.forEach(item -> item.setFormSettingId(add.getFormSettingId())); + aiFormSettingDetailMapper.insertFormSettingDetailBatch(detailList); + } + return flag; + } + + /** + * 修改AI表单设置 + * + * @param bo AI表单设置 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(AiFormSettingBo bo) { + List aiFormSettingDetailList = bo.getAiFormSettingDetailList(); + aiFormSettingDetailMapper.updateBatchById(aiFormSettingDetailList); + AiFormSetting update = MapstructUtils.convert(bo, AiFormSetting.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(AiFormSetting entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除AI表单设置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + ids.forEach(id -> { + aiFormSettingDetailMapper.delete(Wrappers.lambdaQuery() + .eq(AiFormSettingDetail::getFormSettingId, id)); + }); + + return baseMapper.deleteByIds(ids) > 0; + } + + + + + + + + /** + * 查询数据库列表 + * + * @param aiFormSettingBo AiFormSettingBo + * @param pageQuery 包含分页信息的PageQuery对象 + * @return 包含分页结果的TableDataInfo对象 + */ + @DS("#aiFormSettingBo.dataName") + @Override + public TableDataInfo selectPageDbTableList(AiFormSettingBo aiFormSettingBo, PageQuery pageQuery) { + // 获取查询条件 + String tableName = aiFormSettingBo.getTableName(); + String tableComment = aiFormSettingBo.getTableComment(); + + LinkedHashMap> tablesMap = ServiceProxy.metadata().tables(); + if (CollUtil.isEmpty(tablesMap)) { + return TableDataInfo.build(); + } + List tableNames = baseMapper.selectTableNameList(aiFormSettingBo.getDataName()); + String[] tableArrays; + if (CollUtil.isNotEmpty(tableNames)) { + tableArrays = tableNames.toArray(new String[0]); + } else { + tableArrays = new String[0]; + } + // 过滤并转换表格数据 + List tables = tablesMap.values().stream() + .filter(x -> !startWithAnyIgnoreCase(x.getName(), TABLE_IGNORE)) + .filter(x -> { + if (CollUtil.isEmpty(tableNames)) { + return true; + } + return !StringUtils.equalsAnyIgnoreCase(x.getName(), tableArrays); + }) + .filter(x -> { + boolean nameMatches = true; + boolean commentMatches = true; + // 进行表名称的模糊查询 + if (StringUtils.isNotBlank(tableName)) { + nameMatches = StringUtils.containsIgnoreCase(x.getName(), tableName); + } + // 进行表描述的模糊查询 + if (StringUtils.isNotBlank(tableComment)) { + commentMatches = StringUtils.containsIgnoreCase(x.getComment(), tableComment); + } + // 同时匹配名称和描述 + return nameMatches && commentMatches; + }) + .map(x -> { + AiFormSettingVo gen = new AiFormSettingVo(); + gen.setTableName(x.getName()); + gen.setTableComment(x.getComment()); + return gen; + }).toList(); + + IPage page = pageQuery.build(); + page.setTotal(tables.size()); + // 手动分页 set数据 + page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables)); + return TableDataInfo.build(page); + } + + + public static boolean startWithAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) { + // 判断是否是以指定字符串开头 + for (CharSequence searchCharSequence : searchCharSequences) { + if (StringUtils.startsWithIgnoreCase(cs, searchCharSequence)) { + return true; + } + } + return false; + } + + + /** + * 根据表名称查询列信息 + * + * @param tableName 表名称 + * @param dataName 数据源名称 + * @return 列信息 + */ + @DS("#dataName") + @Override + public List selectDbTableColumnsByName(String tableName, String dataName) { + LinkedHashMap columns = ServiceProxy.metadata().columns(tableName); + List aiFormSettingDetailList = new ArrayList<>(); + columns.forEach((columnName, column) -> { + AiFormSettingDetailVo aiFormSettingDetail = new AiFormSettingDetailVo(); + aiFormSettingDetail.setTableName(tableName); + aiFormSettingDetail.setFieldName(column.getName()); + aiFormSettingDetail.setFieldDesc(column.getComment()); + aiFormSettingDetail.setFormProp(convertToCamelCase(column.getName())); + aiFormSettingDetail.setSettingFlag("0"); + + aiFormSettingDetailList.add(aiFormSettingDetail); + }); + return aiFormSettingDetailList; + } + + + /** + * + * @param snakeCaseStr + * @return + */ + public static String convertToCamelCase(String snakeCaseStr) { + // 使用Apache Commons Lang库的核心方法 + // 1. 先用 `split` 按 `_` 分割成单词数组 + // 2. 然后用 `StringUtils.capitalize` 将每个单词首字母大写 + // 3. 最后用 `String.join` 或 `StringUtils.join` 拼接起来 + + if (snakeCaseStr == null || snakeCaseStr.isEmpty()) { + return snakeCaseStr; + } + + // 核心转换逻辑 + String[] words = snakeCaseStr.split("_"); + // 如果字符串中没有下划线,直接返回原字符串(或原字符串的小写形式,根据需求定) + if (words.length == 0) { + return snakeCaseStr; + } + + // 将第一个单词全部转为小写 + StringBuilder result = new StringBuilder(words[0].toLowerCase()); + + // 从第二个单词开始,将每个单词首字母大写后追加 + for (int i = 1; i < words.length; i++) { + result.append(StringUtils.capitalize(words[i].toLowerCase())); + } + + return result.toString(); + } + +} diff --git a/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingDetailMapper.xml b/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingDetailMapper.xml new file mode 100644 index 00000000..ff325515 --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingDetailMapper.xml @@ -0,0 +1,14 @@ + + + + + + insert into ai_form_setting_detail (form_setting_id, table_name, field_name, field_desc, form_prop,setting_flag) + values + + (#{item.formSettingId}, #{item.tableName}, #{item.fieldName}, #{item.fieldDesc}, #{item.formProp},#{item.settingFlag}) + + + diff --git a/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingMapper.xml b/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingMapper.xml new file mode 100644 index 00000000..13f1015e --- /dev/null +++ b/ruoyi-modules/hwmom-ai/src/main/resources/mapper/ai/AiFormSettingMapper.xml @@ -0,0 +1,10 @@ + + + + + +