ruoyi-admin/src/main/java/org/ruoyi/RuoYiAIApplication.java
@@ -3,6 +3,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; /** * å¯å¨ç¨åº @@ -10,6 +12,8 @@ * @author Lion Li */ @SpringBootApplication @EnableScheduling @EnableAsync public class RuoYiAIApplication { public static void main(String[] args) { ruoyi-modules-api/ruoyi-knowledge-api/pom.xml
@@ -114,6 +114,10 @@ <artifactId>commons-io</artifactId> <version>2.17.0</version> </dependency> <dependency> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-system-api</artifactId> </dependency> </dependencies> ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/constant/DealStatus.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package org.ruoyi.constant; /** * @Description: * @Date: 2025/5/14 ä¸å2:04 */ public class DealStatus { //æªå¼å§ public static final Integer STATUS_10 = 10; //è¿è¡ä¸ public static final Integer STATUS_20 = 20; //å·²ç»æ public static final Integer STATUS_30 = 30; //å¤ç失败 public static final Integer STATUS_40 = 40; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/KnowledgeAttach.java
@@ -18,44 +18,66 @@ @TableName("knowledge_attach") public class KnowledgeAttach extends BaseEntity { @Serial private static final long serialVersionUID = 1L; @Serial private static final long serialVersionUID = 1L; /** * */ @TableId(value = "id") private Long id; /** * */ @TableId(value = "id") private Long id; /** * ç¥è¯åºID */ private String kid; /** * ç¥è¯åºID */ private String kid; /** * ææ¡£ID */ private String docId; /** * ææ¡£ID */ private String docId; /** * ææ¡£åç§° */ private String docName; /** * ææ¡£åç§° */ private String docName; /** * ææ¡£ç±»å */ private String docType; /** * ææ¡£ç±»å */ private String docType; /** * ææ¡£å 容 */ private String content; /** * ææ¡£å 容 */ private String content; /** * 夿³¨ */ private String remark; /** * 夿³¨ */ private String remark; /** * 对象åå¨ä¸»é® */ private Long ossId; /** * æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ private Integer picStatus; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ private Integer picAnysStatus; /** * åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ private Integer vectorStatus; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/KnowledgeAttachPic.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,81 @@ package org.ruoyi.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serial; import org.ruoyi.core.domain.BaseEntity; /** * ç¥è¯åºéä»¶å¾çå对象 knowledge_attach_pic * * @author Albert * @date 2025-05-15 */ @Data @EqualsAndHashCode(callSuper = true) @TableName("knowledge_attach_pic") public class KnowledgeAttachPic extends BaseEntity { @Serial private static final long serialVersionUID = 1L; /** * ä¸»é® */ @TableId(value = "id") private Long id; /** * ç¥è¯åºid */ private String kid; /** * éä»¶id */ private String aid; /** * ææ¡£åç§° */ private String docName; /** * ææ¡£ç±»å */ private String docType; /** * ææ¡£å 容 */ private String content; /** * æå¨é¡µæ° */ private Integer pageNum; /** * æå¨é¡µindex */ private Integer indexNum; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ private Integer picAnysStatus; /** * 对象åå¨ä¸»é® */ private Long ossId; /** * 夿³¨ */ private String remark; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/bo/KnowledgeAttachBo.java
@@ -20,47 +20,72 @@ @AutoMapper(target = KnowledgeAttach.class, reverseConvertGenerate = false) public class KnowledgeAttachBo extends BaseEntity { /** * */ @NotNull(message = "ä¸è½ä¸ºç©º", groups = { EditGroup.class }) private Long id; /** * */ @NotNull(message = "ä¸è½ä¸ºç©º", groups = {EditGroup.class}) private Long id; /** * ç¥è¯åºID */ @NotBlank(message = "ç¥è¯åºIDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String kid; /** * ç¥è¯åºID */ @NotBlank(message = "ç¥è¯åºIDä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String kid; /** * ææ¡£ID */ @NotBlank(message = "ææ¡£IDä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String docId; /** * ææ¡£ID */ @NotBlank(message = "ææ¡£IDä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String docId; /** * ææ¡£åç§° */ @NotBlank(message = "ææ¡£åç§°ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String docName; /** * ææ¡£åç§° */ @NotBlank(message = "ææ¡£åç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String docName; /** * ææ¡£ç±»å */ @NotBlank(message = "ææ¡£ç±»åä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String docType; /** * ææ¡£ç±»å */ @NotBlank(message = "ææ¡£ç±»åä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String docType; /** * ææ¡£å 容 */ @NotBlank(message = "ææ¡£å 容ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String content; /** * ææ¡£å 容 */ @NotBlank(message = "ææ¡£å 容ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String content; /** * 夿³¨ */ @NotBlank(message = "夿³¨ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private String remark; /** * 夿³¨ */ @NotBlank(message = "夿³¨ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String remark; /** * 对象åå¨ä¸»é® */ @NotNull(message = "对象åå¨ä¸»é®ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private Long ossId; /** * æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @NotNull(message = "æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private Integer picStatus; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @NotNull(message = "åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private Integer picAnysStatus; /** * åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @NotNull(message = "åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) private Integer vectorStatus; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/bo/KnowledgeAttachPicBo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,90 @@ package org.ruoyi.domain.bo; import org.ruoyi.common.core.validate.AddGroup; import org.ruoyi.common.core.validate.EditGroup; import org.ruoyi.core.domain.BaseEntity; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; import jakarta.validation.constraints.*; import org.ruoyi.domain.KnowledgeAttachPic; /** * ç¥è¯åºéä»¶å¾çåä¸å¡å¯¹è±¡ knowledge_attach_pic * * @author Albert * @date 2025-05-15 */ @Data @EqualsAndHashCode(callSuper = true) @AutoMapper(target = KnowledgeAttachPic.class, reverseConvertGenerate = false) public class KnowledgeAttachPicBo extends BaseEntity { /** * ä¸»é® */ @NotNull(message = "主é®ä¸è½ä¸ºç©º", groups = {EditGroup.class}) private Long id; /** * ç¥è¯åºid */ @NotBlank(message = "ç¥è¯åºidä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String kid; /** * éä»¶id */ @NotBlank(message = "éä»¶idä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String aid; /** * ææ¡£åç§° */ @NotBlank(message = "ææ¡£åç§°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String docName; /** * ææ¡£ç±»å */ @NotBlank(message = "ææ¡£ç±»åä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String docType; /** * ææ¡£å 容 */ @NotBlank(message = "ææ¡£å 容ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String content; /** * æå¨é¡µæ° */ @NotNull(message = "æå¨é¡µæ°ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private Integer pageNum; /** * æå¨é¡µindex */ @NotNull(message = "æå¨é¡µindexä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private Integer indexNum; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @NotNull(message = "åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private Integer picAnysStatus; /** * 对象åå¨ä¸»é® */ @NotNull(message = "对象åå¨ä¸»é®ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private Long ossId; /** * 夿³¨ */ @NotBlank(message = "夿³¨ä¸è½ä¸ºç©º", groups = {AddGroup.class, EditGroup.class}) private String remark; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/vo/KnowledgeAttachPicVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,92 @@ package org.ruoyi.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import java.io.Serial; import java.io.Serializable; import org.ruoyi.domain.KnowledgeAttachPic; /** * ç¥è¯åºéä»¶å¾çåè§å¾å¯¹è±¡ knowledge_attach_pic * * @author Albert * @date 2025-05-15 */ @Data @ExcelIgnoreUnannotated @AutoMapper(target = KnowledgeAttachPic.class) public class KnowledgeAttachPicVo implements Serializable { @Serial private static final long serialVersionUID = 1L; /** * ä¸»é® */ @ExcelProperty(value = "主é®") private Long id; /** * ç¥è¯åºid */ @ExcelProperty(value = "ç¥è¯åºid") private String kid; /** * éä»¶id */ @ExcelProperty(value = "éä»¶id") private String aid; /** * ææ¡£åç§° */ @ExcelProperty(value = "ææ¡£åç§°") private String docName; /** * ææ¡£ç±»å */ @ExcelProperty(value = "ææ¡£ç±»å") private String docType; /** * ææ¡£å 容 */ @ExcelProperty(value = "ææ¡£å 容") private String content; /** * æå¨é¡µæ° */ @ExcelProperty(value = "æå¨é¡µæ°") private Integer pageNum; /** * æå¨é¡µindex */ @ExcelProperty(value = "æå¨é¡µindex") private Integer indexNum; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @ExcelProperty(value = "åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿") private Integer picAnysStatus; /** * 对象åå¨ä¸»é® */ @ExcelProperty(value = "对象åå¨ä¸»é®") private Long ossId; /** * 夿³¨ */ @ExcelProperty(value = "夿³¨") private String remark; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/vo/KnowledgeAttachVo.java
@@ -10,8 +10,6 @@ import java.io.Serializable; /** * ç¥è¯åºéä»¶è§å¾å¯¹è±¡ knowledge_attach * @@ -23,50 +21,74 @@ @AutoMapper(target = KnowledgeAttach.class) public class KnowledgeAttachVo implements Serializable { @Serial private static final long serialVersionUID = 1L; @Serial private static final long serialVersionUID = 1L; /** * */ @ExcelProperty(value = "") private Long id; /** * */ @ExcelProperty(value = "") private Long id; /** * ç¥è¯åºID */ @ExcelProperty(value = "ç¥è¯åºID") private String kid; /** * ç¥è¯åºID */ @ExcelProperty(value = "ç¥è¯åºID") private String kid; /** * ææ¡£ID */ @ExcelProperty(value = "ææ¡£ID") private String docId; /** * ææ¡£ID */ @ExcelProperty(value = "ææ¡£ID") private String docId; /** * ææ¡£åç§° */ @ExcelProperty(value = "ææ¡£åç§°") private String docName; /** * ææ¡£åç§° */ @ExcelProperty(value = "ææ¡£åç§°") private String docName; /** * ææ¡£ç±»å */ @ExcelProperty(value = "ææ¡£ç±»å") private String docType; /** * ææ¡£ç±»å */ @ExcelProperty(value = "ææ¡£ç±»å") private String docType; /** * ææ¡£å 容 */ @ExcelProperty(value = "ææ¡£å 容") private String content; /** * ææ¡£å 容 */ @ExcelProperty(value = "ææ¡£å 容") private String content; /** * 夿³¨ */ @ExcelProperty(value = "夿³¨") private String remark; /** * 夿³¨ */ @ExcelProperty(value = "夿³¨") private String remark; /** * 对象åå¨ä¸»é® */ @ExcelProperty(value = "对象åå¨ä¸»é®") private Long ossId; /** * æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @ExcelProperty(value = "æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿") private Integer picStatus; /** * åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @ExcelProperty(value = "åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿") private Integer picAnysStatus; /** * åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿 */ @ExcelProperty(value = "åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿") private Integer vectorStatus; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/mapper/KnowledgeAttachPicMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,15 @@ package org.ruoyi.mapper; import org.ruoyi.core.mapper.BaseMapperPlus; import org.ruoyi.domain.KnowledgeAttachPic; import org.ruoyi.domain.vo.KnowledgeAttachPicVo; /** * ç¥è¯åºéä»¶å¾çåMapperæ¥å£ * * @author Albert * @date 2025-05-15 */ public interface KnowledgeAttachPicMapper extends BaseMapperPlus<KnowledgeAttachPic, KnowledgeAttachPicVo> { } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/IKnowledgeAttachPicService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,47 @@ package org.ruoyi.service; import java.util.Collection; import java.util.List; import org.ruoyi.core.page.PageQuery; import org.ruoyi.core.page.TableDataInfo; import org.ruoyi.domain.bo.KnowledgeAttachPicBo; import org.ruoyi.domain.vo.KnowledgeAttachPicVo; /** * ç¥è¯åºéä»¶å¾çåServiceæ¥å£ * * @author Albert * @date 2025-05-15 */ public interface IKnowledgeAttachPicService { /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çå */ KnowledgeAttachPicVo queryById(Long id); /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çåå表 */ TableDataInfo<KnowledgeAttachPicVo> queryPageList(KnowledgeAttachPicBo bo, PageQuery pageQuery); /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çåå表 */ List<KnowledgeAttachPicVo> queryList(KnowledgeAttachPicBo bo); /** * æ°å¢ç¥è¯åºéä»¶å¾çå */ Boolean insertByBo(KnowledgeAttachPicBo bo); /** * ä¿®æ¹ç¥è¯åºéä»¶å¾çå */ Boolean updateByBo(KnowledgeAttachPicBo bo); /** * æ ¡éªå¹¶æ¹éå é¤ç¥è¯åºéä»¶å¾çåä¿¡æ¯ */ Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/IKnowledgeInfoService.java
@@ -61,5 +61,5 @@ /** * ä¸ä¼ éä»¶ */ void upload(KnowledgeInfoUploadBo bo); void upload(KnowledgeInfoUploadBo bo) throws Exception; } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/KnowledgeAttachPicServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,123 @@ package org.ruoyi.service.impl; import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.StringUtils; import org.ruoyi.core.page.TableDataInfo; import org.ruoyi.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.ruoyi.domain.KnowledgeAttachPic; import org.ruoyi.domain.bo.KnowledgeAttachPicBo; import org.ruoyi.domain.vo.KnowledgeAttachPicVo; import org.ruoyi.mapper.KnowledgeAttachPicMapper; import org.ruoyi.service.IKnowledgeAttachPicService; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.Collection; /** * ç¥è¯åºéä»¶å¾çåServiceä¸å¡å±å¤ç * * @author ageerle * @date 2025-05-15 */ @RequiredArgsConstructor @Service public class KnowledgeAttachPicServiceImpl implements IKnowledgeAttachPicService { private final KnowledgeAttachPicMapper baseMapper; /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çå */ @Override public KnowledgeAttachPicVo queryById(Long id) { return baseMapper.selectVoById(id); } /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çåå表 */ @Override public TableDataInfo<KnowledgeAttachPicVo> queryPageList(KnowledgeAttachPicBo bo, PageQuery pageQuery) { LambdaQueryWrapper<KnowledgeAttachPic> lqw = buildQueryWrapper(bo); Page<KnowledgeAttachPicVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * æ¥è¯¢ç¥è¯åºéä»¶å¾çåå表 */ @Override public List<KnowledgeAttachPicVo> queryList(KnowledgeAttachPicBo bo) { LambdaQueryWrapper<KnowledgeAttachPic> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper<KnowledgeAttachPic> buildQueryWrapper(KnowledgeAttachPicBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeAttachPic> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeAttachPic::getKid, bo.getKid()); lqw.eq(StringUtils.isNotBlank(bo.getAid()), KnowledgeAttachPic::getAid, bo.getAid()); lqw.like(StringUtils.isNotBlank(bo.getDocName()), KnowledgeAttachPic::getDocName, bo.getDocName()); lqw.eq(StringUtils.isNotBlank(bo.getDocType()), KnowledgeAttachPic::getDocType, bo.getDocType()); lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeAttachPic::getContent, bo.getContent()); lqw.eq(bo.getPageNum() != null, KnowledgeAttachPic::getPageNum, bo.getPageNum()); lqw.eq(bo.getIndexNum() != null, KnowledgeAttachPic::getIndexNum, bo.getIndexNum()); lqw.eq(bo.getPicAnysStatus() != null, KnowledgeAttachPic::getPicAnysStatus, bo.getPicAnysStatus()); lqw.eq(bo.getOssId() != null, KnowledgeAttachPic::getOssId, bo.getOssId()); return lqw; } /** * æ°å¢ç¥è¯åºéä»¶å¾çå */ @Override public Boolean insertByBo(KnowledgeAttachPicBo bo) { KnowledgeAttachPic add = MapstructUtils.convert(bo, KnowledgeAttachPic.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * ä¿®æ¹ç¥è¯åºéä»¶å¾çå */ @Override public Boolean updateByBo(KnowledgeAttachPicBo bo) { KnowledgeAttachPic update = MapstructUtils.convert(bo, KnowledgeAttachPic.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * ä¿ååçæ°æ®æ ¡éª */ private void validEntityBeforeSave(KnowledgeAttachPic entity) { //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ } /** * æ¹éå é¤ç¥è¯åºéä»¶å¾çå */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } return baseMapper.deleteBatchIds(ids) > 0; } } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/KnowledgeAttachServiceImpl.java
@@ -1,5 +1,7 @@ package org.ruoyi.service.impl; import cn.hutool.core.util.ObjectUtil; import java.util.stream.Collectors; import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.StringUtils; import org.ruoyi.core.page.TableDataInfo; @@ -8,8 +10,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.ruoyi.domain.KnowledgeAttachPic; import org.ruoyi.domain.vo.KnowledgeAttachVo; import org.ruoyi.mapper.KnowledgeAttachPicMapper; import org.ruoyi.mapper.KnowledgeFragmentMapper; import org.ruoyi.system.service.ISysOssService; import org.springframework.stereotype.Service; import org.ruoyi.domain.bo.KnowledgeAttachBo; @@ -33,99 +38,130 @@ @Service public class KnowledgeAttachServiceImpl implements IKnowledgeAttachService { private final KnowledgeAttachMapper baseMapper; private final KnowledgeFragmentMapper fragmentMapper; private final KnowledgeAttachMapper baseMapper; private final KnowledgeFragmentMapper fragmentMapper; /** * æ¥è¯¢ç¥è¯åºéä»¶ */ @Override public KnowledgeAttachVo queryById(Long id){ return baseMapper.selectVoById(id); private final ISysOssService ossService; private final KnowledgeAttachPicMapper picMapper; /** * æ¥è¯¢ç¥è¯åºéä»¶ */ @Override public KnowledgeAttachVo queryById(Long id) { return baseMapper.selectVoById(id); } /** * æ¥è¯¢ç¥è¯åºéä»¶å表 */ @Override public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) { LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * æ¥è¯¢ç¥è¯åºéä»¶å表 */ @Override public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) { LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeAttach> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeAttach::getKid, bo.getKid()); lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeAttach::getDocId, bo.getDocId()); lqw.like(StringUtils.isNotBlank(bo.getDocName()), KnowledgeAttach::getDocName, bo.getDocName()); lqw.eq(StringUtils.isNotBlank(bo.getDocType()), KnowledgeAttach::getDocType, bo.getDocType()); lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeAttach::getContent, bo.getContent()); return lqw; } /** * æ°å¢ç¥è¯åºéä»¶ */ @Override public Boolean insertByBo(KnowledgeAttachBo bo) { KnowledgeAttach add = MapstructUtils.convert(bo, KnowledgeAttach.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * æ¥è¯¢ç¥è¯åºéä»¶å表 */ @Override public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) { LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); /** * ä¿®æ¹ç¥è¯åºéä»¶ */ @Override public Boolean updateByBo(KnowledgeAttachBo bo) { KnowledgeAttach update = MapstructUtils.convert(bo, KnowledgeAttach.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * ä¿ååçæ°æ®æ ¡éª */ private void validEntityBeforeSave(KnowledgeAttach entity) { //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ } /** * æ¹éå é¤ç¥è¯åºéä»¶ */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } return baseMapper.deleteBatchIds(ids) > 0; } /** * æ¥è¯¢ç¥è¯åºéä»¶å表 */ @Override public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) { LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); @Override public void removeKnowledgeAttach(String docId) { Map<String, Object> map = new HashMap<>(); map.put("doc_id", docId); List<KnowledgeAttachVo> knowledgeAttachVos = baseMapper.selectVoByMap(map); if (ObjectUtil.isNotEmpty(knowledgeAttachVos)) { Collection<Long> ossIds = knowledgeAttachVos.stream() .map(KnowledgeAttachVo::getOssId) .collect(Collectors.toList()); //å é¤oss ossService.deleteWithValidByIds(ossIds, false); //å é¤å¾çoss List<KnowledgeAttachPic> knowledgeAttachPics = picMapper.selectList( new LambdaQueryWrapper<KnowledgeAttachPic>() .in(KnowledgeAttachPic::getKid, knowledgeAttachVos.stream().map(KnowledgeAttachVo::getKid) .collect(Collectors.toList())) .in(KnowledgeAttachPic::getAid, knowledgeAttachVos.stream().map(KnowledgeAttachVo::getId) .collect(Collectors.toList())) ); if (ObjectUtil.isNotEmpty(knowledgeAttachPics)) { Collection<Long> tossIds = knowledgeAttachPics.stream() .map(KnowledgeAttachPic::getOssId) .collect(Collectors.toList()); ossService.deleteWithValidByIds(tossIds, false); List<Long> collect = knowledgeAttachPics.stream().map(KnowledgeAttachPic::getId) .collect(Collectors.toList()); picMapper.deleteByIds(collect); } } baseMapper.deleteByMap(map); fragmentMapper.deleteByMap(map); } private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeAttach> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeAttach::getKid, bo.getKid()); lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeAttach::getDocId, bo.getDocId()); lqw.like(StringUtils.isNotBlank(bo.getDocName()), KnowledgeAttach::getDocName, bo.getDocName()); lqw.eq(StringUtils.isNotBlank(bo.getDocType()), KnowledgeAttach::getDocType, bo.getDocType()); lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeAttach::getContent, bo.getContent()); return lqw; } /** * æ°å¢ç¥è¯åºéä»¶ */ @Override public Boolean insertByBo(KnowledgeAttachBo bo) { KnowledgeAttach add = MapstructUtils.convert(bo, KnowledgeAttach.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * ä¿®æ¹ç¥è¯åºéä»¶ */ @Override public Boolean updateByBo(KnowledgeAttachBo bo) { KnowledgeAttach update = MapstructUtils.convert(bo, KnowledgeAttach.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * ä¿ååçæ°æ®æ ¡éª */ private void validEntityBeforeSave(KnowledgeAttach entity){ //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ } /** * æ¹éå é¤ç¥è¯åºéä»¶ */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if(isValid){ //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } return baseMapper.deleteBatchIds(ids) > 0; } @Override public void removeKnowledgeAttach(String docId) { Map<String,Object> map = new HashMap<>(); map.put("doc_id",docId); baseMapper.deleteByMap(map); fragmentMapper.deleteByMap(map); } @Override public String translationByFile(MultipartFile file, String targetLanguage) { @Override public String translationByFile(MultipartFile file, String targetLanguage) { /*String fileName = file.getOriginalFilename(); String docType = fileName.substring(fileName.lastIndexOf(".")+1); String content = ""; @@ -173,6 +209,6 @@ throw new BaseException("è°ç¨å¤§æ¨¡å失败ï¼è¯·æ£æ¥å¯é¥æ¯å¦æ£ç¡®ï¼"); } return chatCompletionResponse.getChoices().get(0).getMessage().getContent().toString();*/ return "æ¥å£å¼åä¸!"; } return "æ¥å£å¼åä¸!"; } } ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/PdfImageExtractServiceImpl.java
@@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; import okhttp3.MultipartBody; @@ -23,16 +25,19 @@ /** * PDFå¾çæåæå¡å®ç°ç±» */ @Service //@Service @Slf4j public class PdfImageExtractServiceImpl implements PdfImageExtractService { @Data @AllArgsConstructor //public class PdfImageExtractServiceImpl implements PdfImageExtractService { public class PdfImageExtractServiceImpl { @Value("${pdf.extract.service.url}") // @Value("${pdf.extract.service.url}") private String serviceUrl; @Value("${pdf.extract.ai-api.url}") // @Value("${pdf.extract.ai-api.url}") private String aiApiUrl; @Value("${pdf.extract.ai-api.key}") private String aiApiKey ; // @Value("${pdf.extract.ai-api.key}") private String aiApiKey; private final OkHttpClient client = new Builder() .connectTimeout(100, TimeUnit.SECONDS) @@ -43,7 +48,7 @@ private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); @Override // @Override public byte[] extractImages(MultipartFile pdfFile, String imageFormat, boolean allowDuplicates) throws IOException { // æå»ºmultipartè¯·æ± @@ -77,7 +82,7 @@ * @return æä»¶å å®¹ç»æå表 * @throws IOException 妿APIè°ç¨è¿ç¨ä¸åçé误 */ @Override // @Override public List<PdfFileContentResult> dealFileContent(String[] unzip) throws IOException { List<PdfFileContentResult> results = new ArrayList<>(); int i = 0; @@ -110,6 +115,7 @@ // æ§è¡è¯·æ± try { log.info("=============call=" + ++i); Response response = client.newCall(request).execute(); log.info("=============response=" + response); if (!response.isSuccessful()) { @@ -126,11 +132,10 @@ throw new RuntimeException(e); } } return results; } @Override // @Override public List<PdfFileContentResult> extractImages(MultipartFile file) throws IOException { String format = "png"; boolean allowDuplicates = true; ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/VectorStoreServiceImpl.java
@@ -97,7 +97,7 @@ for (int i = 0; i < chunkList.size(); i++) { Map<String, Object> dataSchema = new HashMap<>(); dataSchema.put("kid", storeEmbeddingBo.getKid()); dataSchema.put("docId", storeEmbeddingBo.getKid()); dataSchema.put("docId", storeEmbeddingBo.getDocId()); dataSchema.put("fid", storeEmbeddingBo.getFids().get(i)); Embedding embedding = embeddingModel.embed(chunkList.get(i)).content(); TextSegment segment = TextSegment.from(chunkList.get(i)); ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/utils/ZipUtils.java
@@ -11,6 +11,8 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.springframework.mock.web.MockMultipartFile; import org.springframework.web.multipart.MultipartFile; /** * ZIPæä»¶å¤çå·¥å ·ç±» @@ -92,4 +94,90 @@ } return base64Contents.toArray(new String[0]); } /** * è§£åZIPæä»¶å¹¶è¿åMultipartFileæ°ç» * * @param zipData ZIPæä»¶çåèæ°ç» * @return MultipartFileæ°ç» * @throws IOException å¦æè§£åè¿ç¨ä¸åçé误 */ public static MultipartFile[] unzipToMultipartFiles(byte[] zipData) throws IOException { List<MultipartFile> multipartFiles = new ArrayList<>(); try (ByteArrayInputStream bis = new ByteArrayInputStream(zipData); ZipInputStream zis = new ZipInputStream(bis)) { ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { if (!zipEntry.isDirectory()) { // 读åæä»¶å 容å°å å ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int read; while ((read = zis.read(buffer)) != -1) { baos.write(buffer, 0, read); } // å建MultipartFile对象 String fileName = zipEntry.getName(); byte[] content = baos.toByteArray(); String contentType = determineContentType(fileName); MultipartFile multipartFile = new MockMultipartFile( fileName, // æä»¶å fileName, // åå§æä»¶å contentType, // å 容类å content // æä»¶å 容 ); multipartFiles.add(multipartFile); } zis.closeEntry(); } } return multipartFiles.toArray(new MultipartFile[0]); } /** * æ ¹æ®æä»¶åç¡®å®å 容类å * * @param fileName æä»¶å * @return å 容类å */ private static String determineContentType(String fileName) { String extension = ""; int i = fileName.lastIndexOf('.'); if (i > 0) { extension = fileName.substring(i + 1).toLowerCase(); } switch (extension) { case "txt": return "text/plain"; case "html": case "htm": return "text/html"; case "pdf": return "application/pdf"; case "jpg": case "jpeg": return "image/jpeg"; case "png": return "image/png"; case "gif": return "image/gif"; case "doc": case "docx": return "application/msword"; case "xls": case "xlsx": return "application/vnd.ms-excel"; case "xml": return "application/xml"; case "json": return "application/json"; default: return "application/octet-stream"; } } } ruoyi-modules-api/ruoyi-system-api/pom.xml
@@ -17,5 +17,11 @@ <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> </dependencies> </project> ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysLogininforService.java
@@ -1,5 +1,6 @@ package org.ruoyi.system.service; import org.ruoyi.common.log.event.LogininforEvent; import org.ruoyi.core.page.PageQuery; import org.ruoyi.core.page.TableDataInfo; import org.ruoyi.system.domain.bo.SysLogininforBo; @@ -44,4 +45,6 @@ * æ¸ ç©ºç³»ç»ç»å½æ¥å¿ */ void cleanLogininfor(); void recordLogininfor(LogininforEvent logininforEvent); } ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysOperLogService.java
@@ -1,5 +1,6 @@ package org.ruoyi.system.service; import org.ruoyi.common.log.event.OperLogEvent; import org.ruoyi.core.page.PageQuery; import org.ruoyi.core.page.TableDataInfo; import org.ruoyi.system.domain.bo.SysOperLogBo; @@ -51,4 +52,5 @@ * æ¸ ç©ºæä½æ¥å¿ */ void cleanOperLog(); void recordOper(OperLogEvent operLogEvent); } ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysOssService.java
@@ -18,16 +18,20 @@ */ public interface ISysOssService { TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery); TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery); List<SysOssVo> listByIds(Collection<Long> ossIds); List<SysOssVo> listByIds(Collection<Long> ossIds); SysOssVo getById(Long ossId); SysOssVo getById(Long ossId); SysOssVo upload(MultipartFile file); SysOssVo upload(MultipartFile file); void download(Long ossId, HttpServletResponse response) throws IOException; void download(Long ossId, HttpServletResponse response) throws IOException; Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); MultipartFile downloadByFile(Long ossId) throws IOException; String downloadByByte(Long ossId) throws IOException; Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); } ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysLogininforServiceImpl.java
@@ -48,6 +48,7 @@ */ @Async @EventListener @Override public void recordLogininfor(LogininforEvent logininforEvent) { HttpServletRequest request = logininforEvent.getRequest(); final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent")); ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysOperLogServiceImpl.java
@@ -42,6 +42,7 @@ */ @Async @EventListener @Override public void recordOper(OperLogEvent operLogEvent) { SysOperLogBo operLog = MapstructUtils.convert(operLogEvent, SysOperLogBo.class); // è¿ç¨æ¥è¯¢æä½å°ç¹ ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java
@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jakarta.servlet.http.HttpServletResponse; import java.util.Base64; import lombok.RequiredArgsConstructor; import org.ruoyi.common.core.constant.CacheNames; import org.ruoyi.common.core.exception.ServiceException; @@ -29,6 +30,7 @@ import org.ruoyi.system.service.ISysOssService; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -48,127 +50,167 @@ @Service public class SysOssServiceImpl implements ISysOssService, OssService { private final SysOssMapper baseMapper; private final SysOssMapper baseMapper; @Override public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) { LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo); Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); List<SysOssVo> filterResult = StreamUtils.toList(result.getRecords(), this::matchingUrl); result.setRecords(filterResult); return TableDataInfo.build(result); @Override public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) { LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo); Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); List<SysOssVo> filterResult = StreamUtils.toList(result.getRecords(), this::matchingUrl); result.setRecords(filterResult); return TableDataInfo.build(result); } @Override public List<SysOssVo> listByIds(Collection<Long> ossIds) { List<SysOssVo> list = new ArrayList<>(); for (Long id : ossIds) { SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); if (ObjectUtil.isNotNull(vo)) { list.add(this.matchingUrl(vo)); } } return list; } @Override public String selectUrlByIds(String ossIds) { List<String> list = new ArrayList<>(); for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) { SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); if (ObjectUtil.isNotNull(vo)) { list.add(this.matchingUrl(vo).getUrl()); } } return String.join(StringUtils.SEPARATOR, list); } private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName()); lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName()); lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix()); lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl()); lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy()); lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService()); return lqw; } @Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId") @Override public SysOssVo getById(Long ossId) { return baseMapper.selectVoById(ossId); } @Override public void download(Long ossId, HttpServletResponse response) throws IOException { SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); if (ObjectUtil.isNull(sysOss)) { throw new ServiceException("æä»¶æ°æ®ä¸åå¨!"); } FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName()); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); OssClient storage = OssFactory.instance(); try (InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { int available = inputStream.available(); IoUtil.copy(inputStream, response.getOutputStream(), available); response.setContentLength(available); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } @Override public String downloadByByte(Long ossId) throws IOException { SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); if (ObjectUtil.isNull(sysOss)) { throw new ServiceException("æä»¶æ°æ®ä¸åå¨!"); } @Override public List<SysOssVo> listByIds(Collection<Long> ossIds) { List<SysOssVo> list = new ArrayList<>(); for (Long id : ossIds) { SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); if (ObjectUtil.isNotNull(vo)) { list.add(this.matchingUrl(vo)); } } return list; OssClient storage = OssFactory.instance(); try (InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { // 读åè¾å ¥æµä¸çææåè byte[] bytes = IoUtil.readBytes(inputStream); // å°åèæ°ç»è½¬æ¢ä¸ºBase64ç¼ç çå符串 return Base64.getEncoder().encodeToString(bytes); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } @Override public MultipartFile downloadByFile(Long ossId) throws IOException { SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); if (ObjectUtil.isNull(sysOss)) { throw new ServiceException("æä»¶æ°æ®ä¸åå¨!"); } @Override public String selectUrlByIds(String ossIds) { List<String> list = new ArrayList<>(); for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) { SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); if (ObjectUtil.isNotNull(vo)) { list.add(this.matchingUrl(vo).getUrl()); } } return String.join(StringUtils.SEPARATOR, list); OssClient storage = OssFactory.instance(); try (InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { byte[] content = IoUtil.readBytes(inputStream); return new MockMultipartFile( sysOss.getFileName(), sysOss.getOriginalName(), MediaType.APPLICATION_OCTET_STREAM_VALUE, content ); } catch (Exception e) { throw new ServiceException(e.getMessage()); } } private LambdaQueryWrapper<SysOss> buildQueryWrapper(SysOssBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<SysOss> lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getFileName()), SysOss::getFileName, bo.getFileName()); lqw.like(StringUtils.isNotBlank(bo.getOriginalName()), SysOss::getOriginalName, bo.getOriginalName()); lqw.eq(StringUtils.isNotBlank(bo.getFileSuffix()), SysOss::getFileSuffix, bo.getFileSuffix()); lqw.eq(StringUtils.isNotBlank(bo.getUrl()), SysOss::getUrl, bo.getUrl()); lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null, SysOss::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime")); lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), SysOss::getCreateBy, bo.getCreateBy()); lqw.eq(StringUtils.isNotBlank(bo.getService()), SysOss::getService, bo.getService()); return lqw; @Override public SysOssVo upload(MultipartFile file) { String originalfileName = file.getOriginalFilename(); String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); OssClient storage = OssFactory.instance(); UploadResult uploadResult; try { uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); } catch (IOException e) { throw new ServiceException(e.getMessage()); } // ä¿åæä»¶ä¿¡æ¯ SysOss oss = new SysOss(); oss.setUrl(uploadResult.getUrl()); oss.setFileSuffix(suffix); oss.setFileName(uploadResult.getFilename()); oss.setOriginalName(originalfileName); oss.setService(storage.getConfigKey()); baseMapper.insert(oss); SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class); return this.matchingUrl(sysOssVo); } @Cacheable(cacheNames = CacheNames.SYS_OSS, key = "#ossId") @Override public SysOssVo getById(Long ossId) { return baseMapper.selectVoById(ossId); @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { // åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } List<SysOss> list = baseMapper.selectBatchIds(ids); for (SysOss sysOss : list) { OssClient storage = OssFactory.instance(sysOss.getService()); storage.delete(sysOss.getUrl()); } return baseMapper.deleteBatchIds(ids) > 0; } @Override public void download(Long ossId, HttpServletResponse response) throws IOException { SysOssVo sysOss = SpringUtils.getAopProxy(this).getById(ossId); if (ObjectUtil.isNull(sysOss)) { throw new ServiceException("æä»¶æ°æ®ä¸åå¨!"); } FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName()); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8"); OssClient storage = OssFactory.instance(); try(InputStream inputStream = storage.getObjectContent(sysOss.getUrl())) { int available = inputStream.available(); IoUtil.copy(inputStream, response.getOutputStream(), available); response.setContentLength(available); } catch (Exception e) { throw new ServiceException(e.getMessage()); } /** * å¹é Url * * @param oss OSS对象 * @return oss å¹é UrlçOSS对象 */ private SysOssVo matchingUrl(SysOssVo oss) { OssClient storage = OssFactory.instance(oss.getService()); // ä» ä¿®æ¹æ¡¶ç±»å为 private çURLï¼ä¸´æ¶URLæ¶é¿ä¸º120s if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) { oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120)); } @Override public SysOssVo upload(MultipartFile file) { String originalfileName = file.getOriginalFilename(); String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length()); OssClient storage = OssFactory.instance(); UploadResult uploadResult; try { uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType()); } catch (IOException e) { throw new ServiceException(e.getMessage()); } // ä¿åæä»¶ä¿¡æ¯ SysOss oss = new SysOss(); oss.setUrl(uploadResult.getUrl()); oss.setFileSuffix(suffix); oss.setFileName(uploadResult.getFilename()); oss.setOriginalName(originalfileName); oss.setService(storage.getConfigKey()); baseMapper.insert(oss); SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class); return this.matchingUrl(sysOssVo); } @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { // åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } List<SysOss> list = baseMapper.selectBatchIds(ids); for (SysOss sysOss : list) { OssClient storage = OssFactory.instance(sysOss.getService()); storage.delete(sysOss.getUrl()); } return baseMapper.deleteBatchIds(ids) > 0; } /** * å¹é Url * * @param oss OSS对象 * @return oss å¹é UrlçOSS对象 */ private SysOssVo matchingUrl(SysOssVo oss) { OssClient storage = OssFactory.instance(oss.getService()); // ä» ä¿®æ¹æ¡¶ç±»å为 private çURLï¼ä¸´æ¶URLæ¶é¿ä¸º120s if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) { oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120)); } return oss; } return oss; } } ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/knowledge/KnowledgeController.java
@@ -52,7 +52,7 @@ private final IKnowledgeFragmentService fragmentService; private final PdfImageExtractService pdfImageExtractService; // private final PdfImageExtractService pdfImageExtractService; /** * æ ¹æ®ç¨æ·ä¿¡æ¯æ¥è¯¢æ¬å°ç¥è¯åº @@ -118,7 +118,7 @@ * ä¸ä¼ ç¥è¯åºéä»¶ */ @PostMapping(value = "/attach/upload") public R<String> upload(KnowledgeInfoUploadBo bo) { public R<String> upload(KnowledgeInfoUploadBo bo) throws Exception { knowledgeInfoService.upload(bo); return R.ok("ä¸ä¼ ç¥è¯åºéä»¶æå!"); } @@ -168,13 +168,13 @@ * æåPDFä¸çå¾çå¹¶è°ç¨gpt-4o-mini,è¯å«å¾çå 容并è¿å * * @param file PDFæä»¶ * @return ä¿åçæä»¶è·¯å¾ä¿¡æ¯ * @return æä»¶åç§°åå¾çå 容 */ @PostMapping("/extract-images") @Operation(summary = "æåPDFä¸çå¾çå¹¶è°ç¨å¤§æ¨¡å,è¯å«å¾çå 容并è¿å", description = "æåPDFä¸çå¾çå¹¶è°ç¨gpt-4o-mini,è¯å«å¾çå 容并è¿å") public R<List<PdfFileContentResult>> extractImages( @RequestPart("file") MultipartFile file ) throws IOException { return R.ok(pdfImageExtractService.extractImages(file)); } // @PostMapping("/extract-images") // @Operation(summary = "æåPDFä¸çå¾çå¹¶è°ç¨å¤§æ¨¡å,è¯å«å¾çå 容并è¿å", description = "æåPDFä¸çå¾çå¹¶è°ç¨gpt-4o-mini,è¯å«å¾çå 容并è¿å") // public R<List<PdfFileContentResult>> extractImages( // @RequestPart("file") MultipartFile file // ) throws IOException { // return R.ok(pdfImageExtractService.extractImages(file)); // } } ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/DealFileService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,385 @@ package org.ruoyi.chat.service.knowledge; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.ruoyi.chain.loader.ResourceLoaderFactory; import org.ruoyi.constant.DealStatus; import org.ruoyi.domain.KnowledgeAttach; import org.ruoyi.domain.KnowledgeAttachPic; import org.ruoyi.domain.KnowledgeFragment; import org.ruoyi.domain.KnowledgeInfo; import org.ruoyi.domain.PdfFileContentResult; import org.ruoyi.domain.bo.StoreEmbeddingBo; import org.ruoyi.domain.vo.ChatModelVo; import org.ruoyi.domain.vo.KnowledgeAttachVo; import org.ruoyi.domain.vo.KnowledgeInfoVo; import org.ruoyi.mapper.KnowledgeAttachMapper; import org.ruoyi.mapper.KnowledgeAttachPicMapper; import org.ruoyi.mapper.KnowledgeFragmentMapper; import org.ruoyi.mapper.KnowledgeInfoMapper; import org.ruoyi.service.IChatModelService; import org.ruoyi.service.VectorStoreService; import org.ruoyi.service.impl.PdfImageExtractServiceImpl; import org.ruoyi.system.domain.vo.SysOssVo; import org.ruoyi.system.service.ISysOssService; import org.ruoyi.utils.ZipUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** * @Description: * @Date: 2025/5/15 ä¸å4:29 */ @Service @RequiredArgsConstructor public class DealFileService { private static final Logger log = LoggerFactory.getLogger(DealFileService.class); private final KnowledgeInfoMapper baseMapper; private final VectorStoreService vectorStoreService; private final ResourceLoaderFactory resourceLoaderFactory; private final KnowledgeFragmentMapper fragmentMapper; private final KnowledgeAttachMapper attachMapper; private final IChatModelService chatModelService; private final ISysOssService ossService; // private final PdfImageExtractService pdfImageExtractService; private final KnowledgeAttachPicMapper picMapper; @Value("${pdf.extract.service.url}") private String serviceUrl; @Value("${pdf.extract.ai-api.url}") private String aiApiUrl; @Value("${pdf.extract.ai-api.key}") private String aiApiKey; @Async public void dealVectorStatus(KnowledgeAttach attachItem) throws Exception { try { //é宿°æ® æ´æ¹VectorStatus å°è¿è¡ä¸ if (attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getId, attachItem.getId()) ) == 0) { return; } List<KnowledgeFragment> knowledgeFragments = fragmentMapper.selectList( new LambdaQueryWrapper<KnowledgeFragment>() .eq(KnowledgeFragment::getKid, attachItem.getKid()) .eq(KnowledgeFragment::getDocId, attachItem.getDocId()) ); if (ObjectUtil.isEmpty(knowledgeFragments)) { throw new Exception("æä»¶æ®µè½ä¸ºç©º"); } List<String> fids = knowledgeFragments.stream() .map(KnowledgeFragment::getFid) .collect(Collectors.toList()); if (ObjectUtil.isEmpty(fids)) { throw new Exception("fids 为空"); } List<String> chunkList = knowledgeFragments.stream() .map(KnowledgeFragment::getContent) .collect(Collectors.toList()); if (ObjectUtil.isEmpty(chunkList)) { throw new Exception("chunkList 为空"); } // éè¿kidæ¥è¯¢ç¥è¯åºä¿¡æ¯ KnowledgeInfoVo knowledgeInfoVo = baseMapper.selectVoOne(Wrappers.<KnowledgeInfo>lambdaQuery() .eq(KnowledgeInfo::getId, attachItem.getKid())); // éè¿å鿍¡åæ¥è¯¢æ¨¡åä¿¡æ¯ ChatModelVo chatModelVo = chatModelService.selectModelByName( knowledgeInfoVo.getEmbeddingModelName()); StoreEmbeddingBo storeEmbeddingBo = new StoreEmbeddingBo(); storeEmbeddingBo.setKid(attachItem.getKid()); storeEmbeddingBo.setDocId(attachItem.getDocId()); storeEmbeddingBo.setFids(fids); storeEmbeddingBo.setChunkList(chunkList); storeEmbeddingBo.setVectorModelName(knowledgeInfoVo.getVectorModelName()); storeEmbeddingBo.setEmbeddingModelName(knowledgeInfoVo.getEmbeddingModelName()); storeEmbeddingBo.setApiKey(chatModelVo.getApiKey()); storeEmbeddingBo.setBaseUrl(chatModelVo.getApiHost()); vectorStoreService.storeEmbeddings(storeEmbeddingBo); //设置å¤ç宿 attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getId, attachItem.getId())); } catch (Exception e) { //设置å¤ç失败 attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_40) .set(KnowledgeAttach::getRemark, attachItem.getRemark() + e.getMessage()) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getId, attachItem.getId())); throw new RuntimeException(e); } } @Async public void dealPicStatus(KnowledgeAttach attachItem) throws Exception { try { //é宿°æ® æ´æ¹picStatus å°è¿è¡ä¸ if (attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getPicStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getId, attachItem.getId()) ) == 0) { return; } //è·åéä»¶ if (ObjectUtil.isEmpty(attachItem.getOssId())) { log.error("==========OssId 为空ï¼attachItem={}", attachItem); throw new Exception("OssId 为空"); } //è·åossæä»¶ MultipartFile multipartFile = ossService.downloadByFile(attachItem.getOssId()); //æè§£åºå¾çZIP PdfImageExtractServiceImpl pdfImageExtractService = new PdfImageExtractServiceImpl(serviceUrl, aiApiUrl, aiApiKey); byte[] pngs = pdfImageExtractService.extractImages(multipartFile, "png", true); //è§£åzipï¼å¾å°å¾çæä»¶ MultipartFile[] multipartFiles = ZipUtils.unzipToMultipartFiles(pngs); //ä¸ä¼ æä»¶å°OSSï¼åå ¥è¡¨ for (MultipartFile file : multipartFiles) { //å æ¥æ¾æ¯å¦æç¸åå¾çåç§°ï¼å åå é¤ List<KnowledgeAttachPic> knowledgeAttachPics = picMapper.selectList( new LambdaQueryWrapper<KnowledgeAttachPic>() .eq(KnowledgeAttachPic::getKid, attachItem.getKid()) .eq(KnowledgeAttachPic::getAid, attachItem.getId()) .eq(KnowledgeAttachPic::getDocName, file.getOriginalFilename()) ); if (ObjectUtil.isNotEmpty(knowledgeAttachPics)) { Collection<Long> ossIds = knowledgeAttachPics.stream() .map(KnowledgeAttachPic::getOssId) .collect(Collectors.toList()); ossService.deleteWithValidByIds(ossIds, false); List<Long> collect = knowledgeAttachPics.stream().map(KnowledgeAttachPic::getId) .collect(Collectors.toList()); picMapper.deleteByIds(collect); } SysOssVo upload = ossService.upload(file); KnowledgeAttachPic entity = new KnowledgeAttachPic(); entity.setKid(attachItem.getKid()); entity.setAid(String.valueOf(attachItem.getId())); entity.setDocName(file.getOriginalFilename()); entity.setDocType( file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1)); entity.setOssId(upload.getOssId()); int[] ints = extractPageNumbers(file.getOriginalFilename()); if (ObjectUtil.isNotEmpty(ints)) { assert ints != null; if (ints.length == 2) { entity.setPageNum(ints[0]); entity.setIndexNum(ints[1]); } } picMapper.insert(entity); } //设置å¤ç宿 attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getId, attachItem.getId())); } catch (Exception e) { //设置å¤ç失败 attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_40) .set(KnowledgeAttach::getRemark, attachItem.getRemark() + e.getMessage()) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_20) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getId, attachItem.getId())); throw new RuntimeException(e); } } @Async public void dealPicAnysStatus(KnowledgeAttachPic picItem) throws Exception { try { //é宿°æ® æ´æ¹ getPicAnysStatus å°è¿è¡ä¸ if (picMapper.update(new LambdaUpdateWrapper<KnowledgeAttachPic>() .set(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_20) .eq(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttachPic::getId, picItem.getId()) ) == 0) { return; } SysOssVo ossVo = ossService.getById(picItem.getOssId()); if (ObjectUtil.isNotEmpty(ossVo)) { String fileStr = ossService.downloadByByte(picItem.getOssId()); //è°ç¨ç¬¬ä¸æ¹ åæå¾çå 容 PdfImageExtractServiceImpl pdfImageExtractService = new PdfImageExtractServiceImpl( serviceUrl, aiApiUrl, aiApiKey); List<PdfFileContentResult> pdfFileContentResults = pdfImageExtractService.dealFileContent( new String[]{fileStr}); if (ObjectUtil.isNotEmpty(pdfFileContentResults)) { for (PdfFileContentResult resultItem : pdfFileContentResults) { //å¾çè§£æå 容ååå°pic表 picMapper.update(new LambdaUpdateWrapper<KnowledgeAttachPic>() .set(KnowledgeAttachPic::getContent, parseContent(resultItem.getContent())) .set(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttachPic::getId, picItem.getId())); //å°å¾çè§£æå 容 åå ¥æ®µè½è¡¨ fragment KnowledgeAttachVo knowledgeAttachVo = attachMapper.selectVoById(picItem.getAid()); if (ObjectUtil.isNotEmpty(knowledgeAttachVo)) { String fid = RandomUtil.randomString(10); KnowledgeFragment knowledgeFragment = new KnowledgeFragment(); knowledgeFragment.setKid(knowledgeAttachVo.getKid()); knowledgeFragment.setDocId(knowledgeAttachVo.getDocId()); knowledgeFragment.setFid(fid); knowledgeFragment.setIdx(0); knowledgeFragment.setContent(parseContent(resultItem.getContent())); knowledgeFragment.setCreateTime(new Date()); fragmentMapper.insert(knowledgeFragment); //æ´æ°attach表ï¼éè¦ææå¾çé½å¤ç宿¯ // æ¥è¯¢é30ç¶æï¼å®æç¶æï¼çè®°å½æ°é long nonStatus30Count = picMapper.selectCount( new LambdaQueryWrapper<KnowledgeAttachPic>() .ne(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttachPic::getAid, picItem.getAid()) ); if (nonStatus30Count == 0) { // æ§è¡è¡¨æ´æ°æä½ attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getId, picItem.getAid())); } } } } } } catch (Exception e) { //失败 picMapper.update(new LambdaUpdateWrapper<KnowledgeAttachPic>() .set(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_40) .set(KnowledgeAttachPic::getRemark, picItem.getRemark() + e.getMessage()) .eq(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_20) .eq(KnowledgeAttachPic::getId, picItem.getId())); throw new RuntimeException(e); } } /** * 仿件å䏿åpageåé¢ç两个æ°å * * @param fileName æä»¶å * @return å å«ä¸¤ä¸ªæ°åçæ°ç»ï¼å¦ææªæ¾å°åè¿ånull */ public static int[] extractPageNumbers(String fileName) { // æ¥æ¾"page_"çä½ç½® int pageIndex = fileName.indexOf("page_"); if (pageIndex == -1) { return null; } // ä»"page_"åå¼å§æªå String afterPage = fileName.substring(pageIndex + 5); // æä¸å线åå² String[] parts = afterPage.split("_"); if (parts.length >= 2) { try { // æå两个æ°å int firstNumber = Integer.parseInt(parts[0]); // 对äºç¬¬äºä¸ªæ°åï¼éè¦å»æå¯è½çæä»¶æ©å±å String secondPart = parts[1]; int dotIndex = secondPart.indexOf("."); if (dotIndex != -1) { secondPart = secondPart.substring(0, dotIndex); } int secondNumber = Integer.parseInt(secondPart); return new int[]{firstNumber, secondNumber}; } catch (NumberFormatException e) { return null; } } return null; } public static String parseContent(String jsonString) { try { // å建ObjectMapperå®ä¾ ObjectMapper objectMapper = new ObjectMapper(); // è§£æJSONå符串 JsonNode rootNode = objectMapper.readTree(jsonString); // è·åchoicesæ°ç»ç第ä¸ä¸ªå ç´ JsonNode choicesNode = rootNode.get("choices"); if (choicesNode != null && choicesNode.isArray() && choicesNode.size() > 0) { // è·å第ä¸ä¸ªchoice JsonNode firstChoice = choicesNode.get(0); // è·åmessageèç¹ JsonNode messageNode = firstChoice.get("message"); if (messageNode != null) { // è·åcontentåæ®µçå¼ JsonNode contentNode = messageNode.get("content"); if (contentNode != null) { return contentNode.asText(); } } } return "æ æ³æ¾å°contentå 容"; } catch (Exception e) { e.printStackTrace(); return "è§£æJSONæ¶åçé误: " + e.getMessage(); } } } ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/KnowledgeInfoServiceImpl.java
@@ -1,43 +1,62 @@ package org.ruoyi.chat.service.knowledge; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.ruoyi.chain.loader.ResourceLoader; import org.ruoyi.chain.loader.ResourceLoaderFactory; import org.ruoyi.common.core.domain.model.LoginUser; import org.ruoyi.common.core.utils.MapstructUtils; import org.ruoyi.common.core.utils.StringUtils; import org.ruoyi.common.satoken.utils.LoginHelper; import org.ruoyi.constant.DealStatus; import org.ruoyi.constant.FileType; import org.ruoyi.core.page.PageQuery; import org.ruoyi.core.page.TableDataInfo; import org.ruoyi.domain.ChatModel; import org.ruoyi.domain.KnowledgeAttach; import org.ruoyi.domain.KnowledgeAttachPic; import org.ruoyi.domain.KnowledgeFragment; import org.ruoyi.domain.KnowledgeInfo; import org.ruoyi.domain.PdfFileContentResult; import org.ruoyi.domain.bo.KnowledgeInfoBo; import org.ruoyi.domain.bo.KnowledgeInfoUploadBo; import org.ruoyi.domain.bo.StoreEmbeddingBo; import org.ruoyi.domain.vo.ChatModelVo; import org.ruoyi.domain.vo.KnowledgeAttachVo; import org.ruoyi.domain.vo.KnowledgeInfoVo; import org.ruoyi.mapper.KnowledgeAttachMapper; import org.ruoyi.mapper.KnowledgeAttachPicMapper; import org.ruoyi.mapper.KnowledgeFragmentMapper; import org.ruoyi.mapper.KnowledgeInfoMapper; import org.ruoyi.service.IChatModelService; import org.ruoyi.service.PdfImageExtractService; import org.ruoyi.service.VectorStoreService; import org.ruoyi.service.IKnowledgeInfoService; import org.ruoyi.service.impl.PdfImageExtractServiceImpl; import org.ruoyi.system.domain.vo.SysOssVo; import org.ruoyi.utils.ZipUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import org.ruoyi.system.service.ISysOssService; import java.io.IOException; import java.util.*; /** * ç¥è¯åºServiceä¸å¡å±å¤ç @@ -49,216 +68,339 @@ @Service public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService { private static final Logger log = LoggerFactory.getLogger(KnowledgeInfoServiceImpl.class); private final KnowledgeInfoMapper baseMapper; private static final Logger log = LoggerFactory.getLogger(KnowledgeInfoServiceImpl.class); private final KnowledgeInfoMapper baseMapper; private final VectorStoreService vectorStoreService; private final VectorStoreService vectorStoreService; private final ResourceLoaderFactory resourceLoaderFactory; private final ResourceLoaderFactory resourceLoaderFactory; private final KnowledgeFragmentMapper fragmentMapper; private final KnowledgeFragmentMapper fragmentMapper; private final KnowledgeAttachMapper attachMapper; private final KnowledgeAttachMapper attachMapper; private final IChatModelService chatModelService; private final IChatModelService chatModelService; /** * æ¥è¯¢ç¥è¯åº */ @Override public KnowledgeInfoVo queryById(Long id){ return baseMapper.selectVoById(id); private final ISysOssService ossService; // private final PdfImageExtractService pdfImageExtractService; private final KnowledgeAttachPicMapper picMapper; private final DealFileService dealFileService; @Value("${pdf.extract.service.url}") private String serviceUrl; @Value("${pdf.extract.ai-api.url}") private String aiApiUrl; @Value("${pdf.extract.ai-api.key}") private String aiApiKey; /** * æ¥è¯¢ç¥è¯åº */ @Override public KnowledgeInfoVo queryById(Long id) { return baseMapper.selectVoById(id); } /** * æ¥è¯¢ç¥è¯åºå表 */ @Override public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) { LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * æ¥è¯¢ç¥è¯åºå表 */ @Override public List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo) { LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeInfo::getKid, bo.getKid()); lqw.eq(bo.getUid() != null, KnowledgeInfo::getUid, bo.getUid()); lqw.like(StringUtils.isNotBlank(bo.getKname()), KnowledgeInfo::getKname, bo.getKname()); lqw.eq(bo.getShare() != null, KnowledgeInfo::getShare, bo.getShare()); lqw.eq(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription()); lqw.eq(StringUtils.isNotBlank(bo.getKnowledgeSeparator()), KnowledgeInfo::getKnowledgeSeparator, bo.getKnowledgeSeparator()); lqw.eq(StringUtils.isNotBlank(bo.getQuestionSeparator()), KnowledgeInfo::getQuestionSeparator, bo.getQuestionSeparator()); lqw.eq(bo.getOverlapChar() != null, KnowledgeInfo::getOverlapChar, bo.getOverlapChar()); lqw.eq(bo.getRetrieveLimit() != null, KnowledgeInfo::getRetrieveLimit, bo.getRetrieveLimit()); lqw.eq(bo.getTextBlockSize() != null, KnowledgeInfo::getTextBlockSize, bo.getTextBlockSize()); return lqw; } /** * æ°å¢ç¥è¯åº */ @Override public Boolean insertByBo(KnowledgeInfoBo bo) { KnowledgeInfo add = MapstructUtils.convert(bo, KnowledgeInfo.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * ä¿®æ¹ç¥è¯åº */ @Override public Boolean updateByBo(KnowledgeInfoBo bo) { KnowledgeInfo update = MapstructUtils.convert(bo, KnowledgeInfo.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * ä¿ååçæ°æ®æ ¡éª */ private void validEntityBeforeSave(KnowledgeInfo entity) { //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ } /** * æ¹éå é¤ç¥è¯åº */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } return baseMapper.deleteBatchIds(ids) > 0; } @Override @Transactional(rollbackFor = Exception.class) public void saveOne(KnowledgeInfoBo bo) { KnowledgeInfo knowledgeInfo = MapstructUtils.convert(bo, KnowledgeInfo.class); if (StringUtils.isBlank(bo.getKid())) { String kid = RandomUtil.randomString(10); if (knowledgeInfo != null) { knowledgeInfo.setKid(kid); knowledgeInfo.setUid(LoginHelper.getLoginUser().getUserId()); } baseMapper.insert(knowledgeInfo); if (knowledgeInfo != null) { vectorStoreService.createSchema(String.valueOf(knowledgeInfo.getId()), bo.getVectorModelName()); } } else { baseMapper.updateById(knowledgeInfo); } } @Override @Transactional(rollbackFor = Exception.class) public void removeKnowledge(String id) { Map<String, Object> map = new HashMap<>(); map.put("kid", id); List<KnowledgeInfoVo> knowledgeInfoList = baseMapper.selectVoByMap(map); check(knowledgeInfoList); // å é¤åéåºä¿¡æ¯ knowledgeInfoList.forEach(knowledgeInfoVo -> { vectorStoreService.removeByKid(String.valueOf(knowledgeInfoVo.getId()), knowledgeInfoVo.getVectorModelName()); }); // å é¤éä»¶åç¥è¯ç段 fragmentMapper.deleteByMap(map); List<KnowledgeAttachVo> knowledgeAttachVos = attachMapper.selectVoByMap(map); if (ObjectUtil.isNotEmpty(knowledgeAttachVos)) { Collection<Long> ossIds = knowledgeAttachVos.stream() .map(KnowledgeAttachVo::getOssId) .collect(Collectors.toList()); //å é¤oss ossService.deleteWithValidByIds(ossIds, false); //å é¤å¾çoss List<KnowledgeAttachPic> knowledgeAttachPics = picMapper.selectList( new LambdaQueryWrapper<KnowledgeAttachPic>() .in(KnowledgeAttachPic::getKid, knowledgeAttachVos.stream().map(KnowledgeAttachVo::getKid) .collect(Collectors.toList())) .in(KnowledgeAttachPic::getAid, knowledgeAttachVos.stream().map(KnowledgeAttachVo::getId) .collect(Collectors.toList())) ); if (ObjectUtil.isNotEmpty(knowledgeAttachPics)) { Collection<Long> tossIds = knowledgeAttachPics.stream() .map(KnowledgeAttachPic::getOssId) .collect(Collectors.toList()); ossService.deleteWithValidByIds(tossIds, false); List<Long> collect = knowledgeAttachPics.stream().map(KnowledgeAttachPic::getId) .collect(Collectors.toList()); picMapper.deleteByIds(collect); } } attachMapper.deleteByMap(map); // å é¤ç¥è¯åº baseMapper.deleteByMap(map); } @Override public void upload(KnowledgeInfoUploadBo bo) { storeContent(bo.getFile(), bo.getKid()); } public void storeContent(MultipartFile file, String kid) { if (file == null || file.isEmpty()) { throw new IllegalArgumentException("File cannot be null or empty"); } /** * æ¥è¯¢ç¥è¯åºå表 */ @Override public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) { LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } /** * æ¥è¯¢ç¥è¯åºå表 */ @Override public List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo) { LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery(); lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeInfo::getKid, bo.getKid()); lqw.eq(bo.getUid() != null, KnowledgeInfo::getUid, bo.getUid()); lqw.like(StringUtils.isNotBlank(bo.getKname()), KnowledgeInfo::getKname, bo.getKname()); lqw.eq(bo.getShare() != null, KnowledgeInfo::getShare, bo.getShare()); lqw.eq(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription()); lqw.eq(StringUtils.isNotBlank(bo.getKnowledgeSeparator()), KnowledgeInfo::getKnowledgeSeparator, bo.getKnowledgeSeparator()); lqw.eq(StringUtils.isNotBlank(bo.getQuestionSeparator()), KnowledgeInfo::getQuestionSeparator, bo.getQuestionSeparator()); lqw.eq(bo.getOverlapChar() != null, KnowledgeInfo::getOverlapChar, bo.getOverlapChar()); lqw.eq(bo.getRetrieveLimit() != null, KnowledgeInfo::getRetrieveLimit, bo.getRetrieveLimit()); lqw.eq(bo.getTextBlockSize() != null, KnowledgeInfo::getTextBlockSize, bo.getTextBlockSize()); return lqw; } /** * æ°å¢ç¥è¯åº */ @Override public Boolean insertByBo(KnowledgeInfoBo bo) { KnowledgeInfo add = MapstructUtils.convert(bo, KnowledgeInfo.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); SysOssVo uploadDto = null; String fileName = file.getOriginalFilename(); List<String> chunkList = new ArrayList<>(); KnowledgeAttach knowledgeAttach = new KnowledgeAttach(); knowledgeAttach.setKid(kid); String docId = RandomUtil.randomString(10); knowledgeAttach.setDocId(docId); knowledgeAttach.setDocName(fileName); knowledgeAttach.setDocType(fileName.substring(fileName.lastIndexOf(".") + 1)); String content = ""; ResourceLoader resourceLoader = resourceLoaderFactory.getLoaderByFileType( knowledgeAttach.getDocType()); List<String> fids = new ArrayList<>(); try { content = resourceLoader.getContent(file.getInputStream()); chunkList = resourceLoader.getChunkList(content, kid); List<KnowledgeFragment> knowledgeFragmentList = new ArrayList<>(); if (CollUtil.isNotEmpty(chunkList)) { // Upload file to OSS uploadDto = ossService.upload(file); for (int i = 0; i < chunkList.size(); i++) { String fid = RandomUtil.randomString(10); fids.add(fid); KnowledgeFragment knowledgeFragment = new KnowledgeFragment(); knowledgeFragment.setKid(kid); knowledgeFragment.setDocId(docId); knowledgeFragment.setFid(fid); knowledgeFragment.setIdx(i); knowledgeFragment.setContent(chunkList.get(i)); knowledgeFragment.setCreateTime(new Date()); knowledgeFragmentList.add(knowledgeFragment); } return flag; } fragmentMapper.insertBatch(knowledgeFragmentList); } catch (IOException e) { log.error("ä¿åç¥è¯åºä¿¡æ¯å¤±è´¥ï¼{}", e.getMessage()); } /** * ä¿®æ¹ç¥è¯åº */ @Override public Boolean updateByBo(KnowledgeInfoBo bo) { KnowledgeInfo update = MapstructUtils.convert(bo, KnowledgeInfo.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; knowledgeAttach.setContent(content); knowledgeAttach.setCreateTime(new Date()); if (ObjectUtil.isNotEmpty(uploadDto) && ObjectUtil.isNotEmpty(uploadDto.getOssId())) { knowledgeAttach.setOssId(uploadDto.getOssId()); //åªæpdfæä»¶ æéè¦æè§£å¾çååæå¾çå 容 if (FileType.PDF.equals(knowledgeAttach.getDocType())) { knowledgeAttach.setPicStatus(DealStatus.STATUS_10); knowledgeAttach.setPicAnysStatus(DealStatus.STATUS_10); } else { knowledgeAttach.setPicStatus(DealStatus.STATUS_30); knowledgeAttach.setPicAnysStatus(DealStatus.STATUS_30); } //æææä»¶ä¸ä¼ åï¼é½éè¦åæ¥å°åéæ°æ®åº knowledgeAttach.setVectorStatus(DealStatus.STATUS_10); } attachMapper.insert(knowledgeAttach); /** * ä¿ååçæ°æ®æ ¡éª */ private void validEntityBeforeSave(KnowledgeInfo entity){ //TODO åä¸äºæ°æ®æ ¡éª,å¦å¯ä¸çº¦æ } /** * æ£æ¥ç¨æ·æ¯å¦æå é¤ç¥è¯åºæé * * @param knowledgeInfoList ç¥è¯åºå表 */ public void check(List<KnowledgeInfoVo> knowledgeInfoList) { LoginUser loginUser = LoginHelper.getLoginUser(); for (KnowledgeInfoVo knowledgeInfoVo : knowledgeInfoList) { if (!knowledgeInfoVo.getUid().equals(loginUser.getUserId())) { throw new SecurityException("æéä¸è¶³"); } } /** * æ¹éå é¤ç¥è¯åº */ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if(isValid){ //TODO åä¸äºä¸å¡ä¸çæ ¡éª,夿æ¯å¦éè¦æ ¡éª } return baseMapper.deleteBatchIds(ids) > 0; } /** * ç¬¬ä¸æ¥ 宿¶ æè§£PDFæä»¶ä¸çå¾ç */ @Scheduled(fixedDelay = 15000) // æ¯3ç§æ§è¡ä¸æ¬¡ public void dealKnowledgeAttachPic() throws Exception { //å¤ç æè§£PDFæä»¶ä¸çå¾ççè®°å½ List<KnowledgeAttach> knowledgeAttaches = attachMapper.selectList( new LambdaQueryWrapper<KnowledgeAttach>() .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) ); log.info("===============æè§£PDFæä»¶ä¸çå¾ç size = {}", knowledgeAttaches.size()); if (ObjectUtil.isNotEmpty(knowledgeAttaches)) { for (KnowledgeAttach attachItem : knowledgeAttaches) { dealFileService.dealPicStatus(attachItem); } } @Override @Transactional(rollbackFor = Exception.class) public void saveOne(KnowledgeInfoBo bo) { KnowledgeInfo knowledgeInfo = MapstructUtils.convert(bo, KnowledgeInfo.class); if (StringUtils.isBlank(bo.getKid())){ String kid = RandomUtil.randomString(10); if (knowledgeInfo != null) { knowledgeInfo.setKid(kid); knowledgeInfo.setUid(LoginHelper.getLoginUser().getUserId()); } baseMapper.insert(knowledgeInfo); if (knowledgeInfo != null) { vectorStoreService.createSchema(String.valueOf(knowledgeInfo.getId()),bo.getVectorModelName()); } }else { baseMapper.updateById(knowledgeInfo); } } /** * ç¬¬äºæ¥ 宿¶ è§£æå¾çå 容 */ @Scheduled(fixedDelay = 15000) public void dealKnowledgeAttachPicAnys() throws Exception { //è·åæªå¤ççå¾çè®°å½ List<KnowledgeAttachPic> knowledgeAttachPics = picMapper.selectList( new LambdaQueryWrapper<KnowledgeAttachPic>() .eq(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_10) .last("LIMIT 20") ); if (ObjectUtil.isNotEmpty(knowledgeAttachPics)) { for (KnowledgeAttachPic picItem : knowledgeAttachPics) { dealFileService.dealPicAnysStatus(picItem); } } @Override @Transactional(rollbackFor = Exception.class) public void removeKnowledge(String id) { Map<String,Object> map = new HashMap<>(); map.put("kid",id); List<KnowledgeInfoVo> knowledgeInfoList = baseMapper.selectVoByMap(map); check(knowledgeInfoList); // å é¤åéåºä¿¡æ¯ knowledgeInfoList.forEach(knowledgeInfoVo -> { vectorStoreService.removeByKid(String.valueOf(knowledgeInfoVo.getId()),knowledgeInfoVo.getVectorModelName()); }); // å é¤éä»¶åç¥è¯ç段 fragmentMapper.deleteByMap(map); attachMapper.deleteByMap(map); // å é¤ç¥è¯åº baseMapper.deleteByMap(map); } /** * ç¬¬ä¸æ¥ 宿¶ å¤ç éä»¶ä¸ä¼ åä¸ä¼ åéæ°æ®åº */ @Scheduled(fixedDelay = 30000) // æ¯3ç§æ§è¡ä¸æ¬¡ public void dealKnowledgeAttachVector() throws Exception { //å¤ç éè¦ä¸ä¼ åéæ°æ®åºçè®°å½ List<KnowledgeAttach> knowledgeAttaches = attachMapper.selectList( new LambdaQueryWrapper<KnowledgeAttach>() .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getPicAnysStatus, DealStatus.STATUS_30) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) ); log.info("===============ä¸ä¼ åéæ°æ®åº size = {}", knowledgeAttaches.size()); if (ObjectUtil.isNotEmpty(knowledgeAttaches)) { for (KnowledgeAttach attachItem : knowledgeAttaches) { dealFileService.dealVectorStatus(attachItem); } } @Override public void upload(KnowledgeInfoUploadBo bo) { storeContent(bo.getFile(), bo.getKid()); } public void storeContent(MultipartFile file, String kid) { String fileName = file.getOriginalFilename(); List<String> chunkList = new ArrayList<>(); KnowledgeAttach knowledgeAttach = new KnowledgeAttach(); knowledgeAttach.setKid(kid); String docId = RandomUtil.randomString(10); knowledgeAttach.setDocId(docId); knowledgeAttach.setDocName(fileName); knowledgeAttach.setDocType(fileName.substring(fileName.lastIndexOf(".")+1)); String content = ""; ResourceLoader resourceLoader = resourceLoaderFactory.getLoaderByFileType(knowledgeAttach.getDocType()); List<String> fids = new ArrayList<>(); try { content = resourceLoader.getContent(file.getInputStream()); chunkList = resourceLoader.getChunkList(content, kid); List<KnowledgeFragment> knowledgeFragmentList = new ArrayList<>(); if (CollUtil.isNotEmpty(chunkList)) { for (int i = 0; i < chunkList.size(); i++) { String fid = RandomUtil.randomString(10); fids.add(fid); KnowledgeFragment knowledgeFragment = new KnowledgeFragment(); knowledgeFragment.setKid(kid); knowledgeFragment.setDocId(docId); knowledgeFragment.setFid(fid); knowledgeFragment.setIdx(i); knowledgeFragment.setContent(chunkList.get(i)); knowledgeFragment.setCreateTime(new Date()); knowledgeFragmentList.add(knowledgeFragment); } } fragmentMapper.insertBatch(knowledgeFragmentList); } catch (IOException e) { log.error("ä¿åç¥è¯åºä¿¡æ¯å¤±è´¥ï¼{}", e.getMessage()); } knowledgeAttach.setContent(content); knowledgeAttach.setCreateTime(new Date()); attachMapper.insert(knowledgeAttach); // éè¿kidæ¥è¯¢ç¥è¯åºä¿¡æ¯ KnowledgeInfoVo knowledgeInfoVo = baseMapper.selectVoOne(Wrappers.<KnowledgeInfo>lambdaQuery() .eq(KnowledgeInfo::getId, kid)); // éè¿å鿍¡åæ¥è¯¢æ¨¡åä¿¡æ¯ ChatModelVo chatModelVo = chatModelService.selectModelByName(knowledgeInfoVo.getEmbeddingModelName()); StoreEmbeddingBo storeEmbeddingBo = new StoreEmbeddingBo(); storeEmbeddingBo.setKid(kid); storeEmbeddingBo.setDocId(docId); storeEmbeddingBo.setFids(fids); storeEmbeddingBo.setChunkList(chunkList); storeEmbeddingBo.setVectorModelName(knowledgeInfoVo.getVectorModelName()); storeEmbeddingBo.setEmbeddingModelName(knowledgeInfoVo.getEmbeddingModelName()); storeEmbeddingBo.setApiKey(chatModelVo.getApiKey()); storeEmbeddingBo.setBaseUrl(chatModelVo.getApiHost()); vectorStoreService.storeEmbeddings(storeEmbeddingBo); } /** * æ£æ¥ç¨æ·æ¯å¦æå é¤ç¥è¯åºæé * * @param knowledgeInfoList ç¥è¯åºå表 */ public void check(List<KnowledgeInfoVo> knowledgeInfoList){ LoginUser loginUser = LoginHelper.getLoginUser(); for (KnowledgeInfoVo knowledgeInfoVo : knowledgeInfoList) { if(!knowledgeInfoVo.getUid().equals(loginUser.getUserId())){ throw new SecurityException("æéä¸è¶³"); } } } } /** * ç¬¬åæ¥ 宿¶ å¤ç å¤±è´¥æ°æ® */ @Scheduled(fixedDelay = 30 * 60 * 1000) public void dealKnowledge40Status() throws Exception { //æè§£PDF失败 éæ°è®¾ç½®ç¶æ attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getPicStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getPicStatus, DealStatus.STATUS_40)); //å°å¾çåæå¤±è´¥çæ°æ® éæ°è®¾ç½®ç¶æ picMapper.update(new LambdaUpdateWrapper<KnowledgeAttachPic>() .set(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_10) .eq(KnowledgeAttachPic::getPicAnysStatus, DealStatus.STATUS_40)); //ä¸ä¼ åéåºå¤±è´¥ éæ°è®¾ç½®ç¶æ attachMapper.update(new LambdaUpdateWrapper<KnowledgeAttach>() .set(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_10) .eq(KnowledgeAttach::getVectorStatus, DealStatus.STATUS_40)); } } ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/util/VelocityUtils.java
@@ -25,386 +25,386 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class VelocityUtils { /** * 项ç®ç©ºé´è·¯å¾ */ private static final String PROJECT_PATH = "main/java"; /** * 项ç®ç©ºé´è·¯å¾ */ private static final String PROJECT_PATH = "main/java"; /** * mybatis空é´è·¯å¾ */ private static final String MYBATIS_PATH = "main/resources/mapper"; /** * mybatis空é´è·¯å¾ */ private static final String MYBATIS_PATH = "main/resources/mapper"; /** * é»è®¤ä¸çº§èåï¼ç³»ç»å·¥å · */ private static final String DEFAULT_PARENT_MENU_ID = "3"; /** * é»è®¤ä¸çº§èåï¼ç³»ç»å·¥å · */ private static final String DEFAULT_PARENT_MENU_ID = "3"; /** * 设置模æ¿åéä¿¡æ¯ * * @return 模æ¿å表 */ public static VelocityContext prepareContext(GenTable genTable) { String moduleName = genTable.getModuleName(); String businessName = genTable.getBusinessName(); String packageName = genTable.getPackageName(); String tplCategory = genTable.getTplCategory(); String functionName = genTable.getFunctionName(); /** * 设置模æ¿åéä¿¡æ¯ * * @return 模æ¿å表 */ public static VelocityContext prepareContext(GenTable genTable) { String moduleName = genTable.getModuleName(); String businessName = genTable.getBusinessName(); String packageName = genTable.getPackageName(); String tplCategory = genTable.getTplCategory(); String functionName = genTable.getFunctionName(); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("tplCategory", genTable.getTplCategory()); velocityContext.put("tableName", genTable.getTableName()); velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "ã请填ååè½åç§°ã"); velocityContext.put("ClassName", genTable.getClassName()); velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); velocityContext.put("moduleName", genTable.getModuleName()); velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); velocityContext.put("businessName", genTable.getBusinessName()); velocityContext.put("basePackage", getPackagePrefix(packageName)); velocityContext.put("packageName", packageName); velocityContext.put("author", genTable.getFunctionAuthor()); velocityContext.put("datetime", DateUtils.getDate()); velocityContext.put("pkColumn", genTable.getPkColumn()); velocityContext.put("importList", getImportList(genTable)); velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); velocityContext.put("columns", genTable.getColumns()); velocityContext.put("table", genTable); velocityContext.put("dicts", getDicts(genTable)); setMenuVelocityContext(velocityContext, genTable); if (GenConstants.TPL_TREE.equals(tplCategory)) { setTreeVelocityContext(velocityContext, genTable); } // 夿æ¯modalè¿æ¯drawer Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); if (ObjectUtil.isNotNull(paramsObj)) { String popupComponent = Optional .ofNullable(paramsObj.getStr("popupComponent")) .orElse("modal"); velocityContext.put("popupComponent", popupComponent); velocityContext.put("PopupComponent", StringUtils.capitalize(popupComponent)); } else { velocityContext.put("popupComponent", "modal"); velocityContext.put("PopupComponent", "Modal"); } // 夿æ¯åçantd表åè¿æ¯useForm表å // native åçantd表å // useForm useVbenForm if (ObjectUtil.isNotNull(paramsObj)) { String formComponent = Optional .ofNullable(paramsObj.getStr("formComponent")) .orElse("useForm"); velocityContext.put("formComponent", formComponent); } return velocityContext; VelocityContext velocityContext = new VelocityContext(); velocityContext.put("tplCategory", genTable.getTplCategory()); velocityContext.put("tableName", genTable.getTableName()); velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "ã请填ååè½åç§°ã"); velocityContext.put("ClassName", genTable.getClassName()); velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); velocityContext.put("moduleName", genTable.getModuleName()); velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); velocityContext.put("businessName", genTable.getBusinessName()); velocityContext.put("basePackage", getPackagePrefix(packageName)); velocityContext.put("packageName", packageName); velocityContext.put("author", genTable.getFunctionAuthor()); velocityContext.put("datetime", DateUtils.getDate()); velocityContext.put("pkColumn", genTable.getPkColumn()); velocityContext.put("importList", getImportList(genTable)); velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); velocityContext.put("columns", genTable.getColumns()); velocityContext.put("table", genTable); velocityContext.put("dicts", getDicts(genTable)); setMenuVelocityContext(velocityContext, genTable); if (GenConstants.TPL_TREE.equals(tplCategory)) { setTreeVelocityContext(velocityContext, genTable); } public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String parentMenuId = getParentMenuId(paramsObj); context.put("parentMenuId", parentMenuId); // 夿æ¯modalè¿æ¯drawer Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); if (ObjectUtil.isNotNull(paramsObj)) { String popupComponent = Optional .ofNullable(paramsObj.getStr("popupComponent")) .orElse("modal"); velocityContext.put("popupComponent", popupComponent); velocityContext.put("PopupComponent", StringUtils.capitalize(popupComponent)); } else { velocityContext.put("popupComponent", "modal"); velocityContext.put("PopupComponent", "Modal"); } // 夿æ¯åçantd表åè¿æ¯useForm表å // native åçantd表å // useForm useVbenForm if (ObjectUtil.isNotNull(paramsObj)) { String formComponent = Optional .ofNullable(paramsObj.getStr("formComponent")) .orElse("useForm"); velocityContext.put("formComponent", formComponent); } return velocityContext; } public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String treeCode = getTreecode(paramsObj); String treeParentCode = getTreeParentCode(paramsObj); String treeName = getTreeName(paramsObj); public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String parentMenuId = getParentMenuId(paramsObj); context.put("parentMenuId", parentMenuId); } context.put("treeCode", treeCode); context.put("treeParentCode", treeParentCode); context.put("treeName", treeName); context.put("expandColumn", getExpandColumn(genTable)); if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE)); } if (paramsObj.containsKey(GenConstants.TREE_NAME)) { context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME)); } public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String treeCode = getTreecode(paramsObj); String treeParentCode = getTreeParentCode(paramsObj); String treeName = getTreeName(paramsObj); context.put("treeCode", treeCode); context.put("treeParentCode", treeParentCode); context.put("treeName", treeName); context.put("expandColumn", getExpandColumn(genTable)); if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE)); } if (paramsObj.containsKey(GenConstants.TREE_NAME)) { context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME)); } } /** * è·å模æ¿ä¿¡æ¯ * * @return 模æ¿å表 */ public static List<String> getTemplateList(String tplCategory) { List<String> templates = new ArrayList<>(); templates.add("vm/java/domain.java.vm"); templates.add("vm/java/vo.java.vm"); templates.add("vm/java/bo.java.vm"); templates.add("vm/java/mapper.java.vm"); templates.add("vm/java/service.java.vm"); templates.add("vm/java/serviceImpl.java.vm"); templates.add("vm/java/controller.java.vm"); templates.add("vm/xml/mapper.xml.vm"); if (DataBaseHelper.isOracle()) { templates.add("vm/sql/oracle/sql.vm"); } else if (DataBaseHelper.isPostgerSql()) { templates.add("vm/sql/postgres/sql.vm"); } else if (DataBaseHelper.isSqlServer()) { templates.add("vm/sql/sqlserver/sql.vm"); } else { templates.add("vm/sql/sql.vm"); } templates.add("vm/ts/api.ts.vm"); templates.add("vm/ts/types.ts.vm"); if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add("vm/vue/index.vue.vm"); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vue/index-tree.vue.vm"); } /** * è·å模æ¿ä¿¡æ¯ * * @return 模æ¿å表 * æ·»å vben5 */ public static List<String> getTemplateList(String tplCategory) { List<String> templates = new ArrayList<>(); templates.add("vm/java/domain.java.vm"); templates.add("vm/java/vo.java.vm"); templates.add("vm/java/bo.java.vm"); templates.add("vm/java/mapper.java.vm"); templates.add("vm/java/service.java.vm"); templates.add("vm/java/serviceImpl.java.vm"); templates.add("vm/java/controller.java.vm"); templates.add("vm/xml/mapper.xml.vm"); if (DataBaseHelper.isOracle()) { templates.add("vm/sql/oracle/sql.vm"); } else if (DataBaseHelper.isPostgerSql()) { templates.add("vm/sql/postgres/sql.vm"); } else if (DataBaseHelper.isSqlServer()) { templates.add("vm/sql/sqlserver/sql.vm"); } else { templates.add("vm/sql/sql.vm"); } templates.add("vm/ts/api.ts.vm"); templates.add("vm/ts/types.ts.vm"); if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add("vm/vue/index.vue.vm"); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vue/index-tree.vue.vm"); } /** * æ·»å vben5 */ templates.add("vm/vben5/api/index.ts.vm"); templates.add("vm/vben5/api/model.d.ts.vm"); templates.add("vm/vben5/views/data.ts.vm"); if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add("vm/vben5/views/index_vben.vue.vm"); templates.add("vm/vben5/views/popup.vue.vm"); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vben5/views/index_vben_tree.vue.vm"); templates.add("vm/vben5/views/popup_tree.vue.vm"); } return templates; templates.add("vm/vben5/api/index.ts.vm"); templates.add("vm/vben5/api/model.d.ts.vm"); templates.add("vm/vben5/views/data.ts.vm"); if (GenConstants.TPL_CRUD.equals(tplCategory)) { templates.add("vm/vben5/views/index_vben.vue.vm"); templates.add("vm/vben5/views/popup.vue.vm"); } else if (GenConstants.TPL_TREE.equals(tplCategory)) { templates.add("vm/vben5/views/index_vben_tree.vue.vm"); templates.add("vm/vben5/views/popup_tree.vue.vm"); } /** * è·åæä»¶å */ public static String getFileName(String template, GenTable genTable) { // æä»¶åç§° String fileName = ""; // å è·¯å¾ String packageName = genTable.getPackageName(); // 模åå String moduleName = genTable.getModuleName(); // 大åç±»å String className = genTable.getClassName(); // ä¸å¡åç§° String businessName = genTable.getBusinessName(); return templates; } String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); String mybatisPath = MYBATIS_PATH + "/" + moduleName; String vuePath = "vue"; /** * è·åæä»¶å */ public static String getFileName(String template, GenTable genTable) { // æä»¶åç§° String fileName = ""; // å è·¯å¾ String packageName = genTable.getPackageName(); // 模åå String moduleName = genTable.getModuleName(); // 大åç±»å String className = genTable.getClassName(); // ä¸å¡åç§° String businessName = genTable.getBusinessName(); if (template.contains("domain.java.vm")) { fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); } if (template.contains("vo.java.vm")) { fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); } if (template.contains("bo.java.vm")) { fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className); } if (template.contains("mapper.java.vm")) { fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); } else if (template.contains("service.java.vm")) { fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); } else if (template.contains("serviceImpl.java.vm")) { fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); } else if (template.contains("controller.java.vm")) { fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); } else if (template.contains("mapper.xml.vm")) { fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); } else if (template.contains("sql.vm")) { fileName = businessName + "Menu.sql"; } else if (template.contains("api.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/index.ts", vuePath, moduleName, businessName); } else if (template.contains("types.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName); } else if (template.contains("index.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } else if (template.contains("index-tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); String mybatisPath = MYBATIS_PATH + "/" + moduleName; String vuePath = "vue"; // 夿æ¯modalè¿æ¯drawer Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); String popupComponent = "modal"; if (ObjectUtil.isNotNull(paramsObj)) { popupComponent = Optional .ofNullable(paramsObj.getStr("popupComponent")) .orElse("modal"); } String vben5Path = "vben5"; if (template.contains("vm/vben5/api/index.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/index.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/api/model.d.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/model.d.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/index_vben.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/index_vben_tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/data.ts.vm")) { fileName = StringUtils.format("{}/views/{}/{}/data.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/popup.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); } if (template.contains("vm/vben5/views/popup_tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); } return fileName; if (template.contains("domain.java.vm")) { fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); } if (template.contains("vo.java.vm")) { fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); } if (template.contains("bo.java.vm")) { fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className); } if (template.contains("mapper.java.vm")) { fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); } else if (template.contains("service.java.vm")) { fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); } else if (template.contains("serviceImpl.java.vm")) { fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); } else if (template.contains("controller.java.vm")) { fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); } else if (template.contains("mapper.xml.vm")) { fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); } else if (template.contains("sql.vm")) { fileName = businessName + "Menu.sql"; } else if (template.contains("api.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/index.ts", vuePath, moduleName, businessName); } else if (template.contains("types.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName); } else if (template.contains("index.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } else if (template.contains("index-tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); } /** * è·åå åç¼ * * @param packageName å åç§° * @return å åç¼åç§° */ public static String getPackagePrefix(String packageName) { int lastIndex = packageName.lastIndexOf("."); return StringUtils.substring(packageName, 0, lastIndex); // 夿æ¯modalè¿æ¯drawer Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); String popupComponent = "modal"; if (ObjectUtil.isNotNull(paramsObj)) { popupComponent = Optional .ofNullable(paramsObj.getStr("popupComponent")) .orElse("modal"); } String vben5Path = "vben5"; if (template.contains("vm/vben5/api/index.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/index.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/api/model.d.ts.vm")) { fileName = StringUtils.format("{}/api/{}/{}/model.d.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/index_vben.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/index_vben_tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/index.vue", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/data.ts.vm")) { fileName = StringUtils.format("{}/views/{}/{}/data.ts", vben5Path, moduleName, businessName); } if (template.contains("vm/vben5/views/popup.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); } if (template.contains("vm/vben5/views/popup_tree.vue.vm")) { fileName = StringUtils.format("{}/views/{}/{}/{}-{}.vue", vben5Path, moduleName, businessName, businessName, popupComponent); } /** * æ ¹æ®åç±»åè·åå¯¼å ¥å * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return è¿åéè¦å¯¼å ¥çå å表 */ public static HashSet<String> getImportList(GenTable genTable) { List<GenTableColumn> columns = genTable.getColumns(); HashSet<String> importList = new HashSet<>(); for (GenTableColumn column : columns) { if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) { importList.add("java.util.Date"); importList.add("com.fasterxml.jackson.annotation.JsonFormat"); } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) { importList.add("java.math.BigDecimal"); } else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) { importList.add("org.dromara.common.translation.annotation.Translation"); importList.add("org.dromara.common.translation.constant.TransConstant"); } return fileName; } /** * è·åå åç¼ * * @param packageName å åç§° * @return å åç¼åç§° */ public static String getPackagePrefix(String packageName) { int lastIndex = packageName.lastIndexOf("."); return StringUtils.substring(packageName, 0, lastIndex); } /** * æ ¹æ®åç±»åè·åå¯¼å ¥å * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return è¿åéè¦å¯¼å ¥çå å表 */ public static HashSet<String> getImportList(GenTable genTable) { List<GenTableColumn> columns = genTable.getColumns(); HashSet<String> importList = new HashSet<>(); for (GenTableColumn column : columns) { if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) { importList.add("java.util.Date"); importList.add("com.fasterxml.jackson.annotation.JsonFormat"); } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) { importList.add("java.math.BigDecimal"); } else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) { importList.add("org.dromara.common.translation.annotation.Translation"); importList.add("org.dromara.common.translation.constant.TransConstant"); } } return importList; } /** * æ ¹æ®åç±»åè·ååå ¸ç» * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return è¿ååå ¸ç» */ public static String getDicts(GenTable genTable) { List<GenTableColumn> columns = genTable.getColumns(); Set<String> dicts = new HashSet<>(); addDicts(dicts, columns); return StringUtils.join(dicts, ", "); } /** * æ·»å åå ¸å表 * * @param dicts åå ¸å表 * @param columns åéå */ public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) { for (GenTableColumn column : columns) { if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( column.getHtmlType(), new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) { dicts.add("'" + column.getDictType() + "'"); } } } /** * è·åæéåç¼ * * @param moduleName 模ååç§° * @param businessName ä¸å¡åç§° * @return è¿åæéåç¼ */ public static String getPermissionPrefix(String moduleName, String businessName) { return StringUtils.format("{}:{}", moduleName, businessName); } /** * è·åä¸çº§èåIDåæ®µ * * @param paramsObj çæå ¶ä»é项 * @return ä¸çº§èåIDåæ®µ */ public static String getParentMenuId(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) { return paramsObj.getStr(GenConstants.PARENT_MENU_ID); } return DEFAULT_PARENT_MENU_ID; } /** * è·åæ ç¼ç * * @param paramsObj çæå ¶ä»é项 * @return æ ç¼ç */ public static String getTreecode(Map<String, Object> paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) { return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE))); } return StringUtils.EMPTY; } /** * è·åæ ç¶ç¼ç * * @param paramsObj çæå ¶ä»é项 * @return æ ç¶ç¼ç */ public static String getTreeParentCode(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE)); } return StringUtils.EMPTY; } /** * è·åæ åç§° * * @param paramsObj çæå ¶ä»é项 * @return æ åç§° */ public static String getTreeName(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) { return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME)); } return StringUtils.EMPTY; } /** * è·åéè¦å¨åªä¸åä¸é¢æ¾ç¤ºå±å¼æé® * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return å±å¼æé®ååºå· */ public static int getExpandColumn(GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String treeName = paramsObj.getStr(GenConstants.TREE_NAME); int num = 0; for (GenTableColumn column : genTable.getColumns()) { if (column.isList()) { num++; String columnName = column.getColumnName(); if (columnName.equals(treeName)) { break; } return importList; } } /** * æ ¹æ®åç±»åè·ååå ¸ç» * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return è¿ååå ¸ç» */ public static String getDicts(GenTable genTable) { List<GenTableColumn> columns = genTable.getColumns(); Set<String> dicts = new HashSet<>(); addDicts(dicts, columns); return StringUtils.join(dicts, ", "); } /** * æ·»å åå ¸å表 * * @param dicts åå ¸å表 * @param columns åéå */ public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) { for (GenTableColumn column : columns) { if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( column.getHtmlType(), new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) { dicts.add("'" + column.getDictType() + "'"); } } } /** * è·åæéåç¼ * * @param moduleName 模ååç§° * @param businessName ä¸å¡åç§° * @return è¿åæéåç¼ */ public static String getPermissionPrefix(String moduleName, String businessName) { return StringUtils.format("{}:{}", moduleName, businessName); } /** * è·åä¸çº§èåIDåæ®µ * * @param paramsObj çæå ¶ä»é项 * @return ä¸çº§èåIDåæ®µ */ public static String getParentMenuId(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) { return paramsObj.getStr(GenConstants.PARENT_MENU_ID); } return DEFAULT_PARENT_MENU_ID; } /** * è·åæ ç¼ç * * @param paramsObj çæå ¶ä»é项 * @return æ ç¼ç */ public static String getTreecode(Map<String, Object> paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) { return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE))); } return StringUtils.EMPTY; } /** * è·åæ ç¶ç¼ç * * @param paramsObj çæå ¶ä»é项 * @return æ ç¶ç¼ç */ public static String getTreeParentCode(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE)); } return StringUtils.EMPTY; } /** * è·åæ åç§° * * @param paramsObj çæå ¶ä»é项 * @return æ åç§° */ public static String getTreeName(Dict paramsObj) { if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) { return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME)); } return StringUtils.EMPTY; } /** * è·åéè¦å¨åªä¸åä¸é¢æ¾ç¤ºå±å¼æé® * * @param genTable ä¸å¡è¡¨å¯¹è±¡ * @return å±å¼æé®ååºå· */ public static int getExpandColumn(GenTable genTable) { String options = genTable.getOptions(); Dict paramsObj = JsonUtils.parseMap(options); String treeName = paramsObj.getStr(GenConstants.TREE_NAME); int num = 0; for (GenTableColumn column : genTable.getColumns()) { if (column.isList()) { num++; String columnName = column.getColumnName(); if (columnName.equals(treeName)) { break; } } } return num; } return num; } } script/sql/update/202505141010.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,10 @@ ALTER TABLE `knowledge_attach` ADD COLUMN `oss_id` bigint(20) NOT NULL COMMENT '对象åå¨ä¸»é®' AFTER `remark`, ADD COLUMN `pic_status` tinyint(1) NOT NULL DEFAULT 10 COMMENT 'æè§£å¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿' AFTER `oss_id`, ADD COLUMN `pic_anys_status` tinyint(1) NOT NULL DEFAULT 10 COMMENT 'åæå¾çç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿' AFTER `pic_status`, ADD COLUMN `vector_status` tinyint(1) NOT NULL DEFAULT 10 COMMENT 'åå ¥åéæ°æ®åºç¶æ10æªå¼å§ï¼20è¿è¡ä¸ï¼30已宿' AFTER `pic_anys_status`, DROP PRIMARY KEY, ADD PRIMARY KEY (`id`) USING BTREE; ALTER TABLE `knowledge_attach` MODIFY COLUMN `remark` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '夿³¨' AFTER `update_time`;