Commit 3344c79c authored by 林洋洋's avatar 林洋洋

切片相关代码提交

parent 67d9f272
...@@ -24,7 +24,7 @@ public class DocumentSegmentResult { ...@@ -24,7 +24,7 @@ public class DocumentSegmentResult {
/** /**
* 文件名 * 文件名
*/ */
@Schema(description = "文件") @Schema(description = "文件路径")
private String filePath; private String filePath;
/** /**
...@@ -39,6 +39,12 @@ public class DocumentSegmentResult { ...@@ -39,6 +39,12 @@ public class DocumentSegmentResult {
@Schema(description = "总分段数") @Schema(description = "总分段数")
private Integer totalSegments; private Integer totalSegments;
/**
* 总分段数
*/
@Schema(description = "文件大小")
private Long fileSize;
/** /**
* 文档分段详情 * 文档分段详情
...@@ -68,7 +74,7 @@ public class DocumentSegmentResult { ...@@ -68,7 +74,7 @@ public class DocumentSegmentResult {
/** /**
* 分段token数(预估) * 分段token数(预估)
*/ */
@Schema(description = "分段token数(预估)") @Schema(description = "标题")
private Integer tokenCount; private String title;
} }
} }
\ No newline at end of file
...@@ -83,6 +83,11 @@ public class KnowledgeDocument extends BaseEntity { ...@@ -83,6 +83,11 @@ public class KnowledgeDocument extends BaseEntity {
@Schema(description = "总token数量") @Schema(description = "总token数量")
private Integer tokenCount; private Integer tokenCount;
/**
* 分段数量
*/
@Schema(description = "启用状态 0停用 1启用")
private Integer isEnabled;
/** /**
* 删除标记,0未删除,1已删除 * 删除标记,0未删除,1已删除
*/ */
......
//package com.ask.config;
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.scheduling.annotation.EnableAsync;
//import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
//
//import java.util.concurrent.Executor;
//import java.util.concurrent.ThreadPoolExecutor;
//
///**
// * 异步配置类
// *
// * @author ai
// * @date 2024/12/19
// */
//@Slf4j
//@Configuration
//@EnableAsync
//public class AsyncConfig {
//
// /**
// * 向量化任务执行器
// */
// @Bean("vectorizeExecutor")
// public Executor vectorizeExecutor() {
// ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// executor.setCorePoolSize(2);
// executor.setMaxPoolSize(5);
// executor.setQueueCapacity(100);
// executor.setKeepAliveSeconds(60);
// executor.setThreadNamePrefix("vectorize-");
// executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// executor.setWaitForTasksToCompleteOnShutdown(true);
// executor.setAwaitTerminationSeconds(60);
// executor.initialize();
//
// log.info("向量化任务执行器初始化完成");
// return executor;
// }
//}
\ No newline at end of file
//package com.ask.config;
//
//import com.pig4cloud.pig.ask.api.entity.GenDatasourceConf;
//import com.pig4cloud.pig.ask.service.GenDatasourceConfService;
//import org.jasypt.encryption.StringEncryptor;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.CommandLineRunner;
//import org.springframework.stereotype.Component;
//
//import java.util.List;
//
//@Component
//public class InitDataBase implements CommandLineRunner {
//
// @Autowired
// private GenDatasourceConfService genDatasourceConfService;
// @Autowired
// private StringEncryptor stringEncryptor;
//
// @Override
// public void run(String... args) throws Exception {
// List<GenDatasourceConf> genDatasourceConfList = genDatasourceConfService.list();
// genDatasourceConfList.forEach(conf->{
// conf.setPassword(stringEncryptor.decrypt(conf.getPassword()));
// genDatasourceConfService.addDynamicDataSource(conf);
// });
// }
//}
package com.ask.controller;
import com.ask.api.entity.AskVectorStore;
import com.ask.common.core.R;
import com.ask.service.AskVectorStoreService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 向量存储管理
*
* @author ai
* @date 2024/12/20
*/
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/vector/store")
@Tag(description = "askVectorStore", name = "向量存储管理")
public class AskVectorStoreController {
private final AskVectorStoreService askVectorStoreService;
private final ObjectMapper objectMapper;
/**
* 分页查询向量存储
*
* @param page 分页对象
* @param documentId 文档ID(非必填)
* @param content 内容关键词(非必填,模糊搜索)
* @return 分页数据
*/
@Operation(summary = "分页查询向量存储", description = "分页查询向量存储数据(不包含向量字段)")
@GetMapping("/page")
public R<IPage<AskVectorStore>> getPage(Page page,
@Parameter(description = "文档ID") @RequestParam Long documentId,
@Parameter(description = "内容关键词") @RequestParam(required = false) String content,
@Parameter(description = "标题关键词") @RequestParam(required = false) String title
) {
LambdaQueryWrapper<AskVectorStore> wrapper = Wrappers.lambdaQuery(AskVectorStore.class)
.like(org.apache.commons.lang3.StringUtils.isNoneBlank(content), AskVectorStore::getContent, content.trim())
.like(org.apache.commons.lang3.StringUtils.isNoneBlank(title), AskVectorStore::getContent, title.trim())
.eq(AskVectorStore::getDocumentId, documentId)
.orderByDesc(AskVectorStore::getId);
IPage<AskVectorStore> result = askVectorStoreService.page(page, wrapper);
return R.ok(result);
}
/**
* 通过ID查询向量存储
*
* @param id ID
* @return 向量存储数据
*/
@Operation(summary = "通过ID查询", description = "通过ID查询向量存储数据(不包含向量字段)")
@GetMapping("/{id}")
public R<AskVectorStore> getById(@PathVariable("id") String id) {
if (!StringUtils.hasText(id)) {
return R.failed("ID不能为空");
}
return R.ok(askVectorStoreService.getById(id));
}
/**
* 修改切片启用状态
*
* @param segmentId 切片ID
* @param isEnabled 启用状态(1:启用,0:禁用)
* @return 修改结果
*/
@Operation(summary = "修改切片启用状态", description = "修改指定切片的启用状态")
@PutMapping("/segment/status/{segmentId}")
public R<Boolean> updateSegmentStatus(@Parameter(description = "切片ID") @PathVariable String segmentId,
@Parameter(description = "启用状态(1:启用,0:禁用)") @RequestParam Integer isEnabled) {
return R.ok(askVectorStoreService.update(Wrappers.<AskVectorStore>lambdaUpdate().eq(AskVectorStore::getId, segmentId)
.set(AskVectorStore::getIsEnabled, isEnabled)));
}
/**
* 修改向量存储
*
* @param askVectorStore 向量存储数据
* @return 操作结果
*/
@Operation(summary = "修改向量存储", description = "修改向量存储数据")
@PutMapping
public R<Boolean> updateById(@Valid @RequestBody AskVectorStore askVectorStore) {
if (!StringUtils.hasText(askVectorStore.getId())) {
return R.failed("ID不能为空");
}
boolean result = askVectorStoreService.updateById(askVectorStore);
return R.ok(result, result ? "修改成功" : "修改失败");
}
/**
* 批量删除向量存储
*
* @param ids ID列表
* @return 操作结果
*/
@Operation(summary = "批量删除", description = "批量删除向量存储数据")
@DeleteMapping("/batch")
public R<Boolean> removeBatchByIds(@RequestBody List<String> ids) {
if (ids == null || ids.isEmpty()) {
return R.failed("ID列表不能为空");
}
try {
boolean result = askVectorStoreService.removeByIds(ids);
return R.ok(result, result ? "批量删除成功" : "批量删除失败");
} catch (Exception e) {
log.error("批量删除向量存储失败,IDs: {}, 错误: {}", ids, e.getMessage(), e);
return R.failed("批量删除失败:" + e.getMessage());
}
}
}
...@@ -5,10 +5,12 @@ import cn.hutool.core.util.IdUtil; ...@@ -5,10 +5,12 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.ask.api.dto.DocumentSegmentRequest; import com.ask.api.dto.DocumentSegmentRequest;
import com.ask.api.dto.DocumentSegmentResult; import com.ask.api.dto.DocumentSegmentResult;
import com.ask.api.entity.AskVectorStore;
import com.ask.api.entity.KnowledgeDocument; import com.ask.api.entity.KnowledgeDocument;
import com.ask.api.entity.SysFile; import com.ask.api.entity.SysFile;
import com.ask.common.core.FileTemplate; import com.ask.common.core.FileTemplate;
import com.ask.common.core.R; import com.ask.common.core.R;
import com.ask.service.AskVectorStoreService;
import com.ask.service.KnowledgeDocumentService; import com.ask.service.KnowledgeDocumentService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
...@@ -22,6 +24,7 @@ import lombok.RequiredArgsConstructor; ...@@ -22,6 +24,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
...@@ -46,65 +49,69 @@ public class KnowledgeDocumentController { ...@@ -46,65 +49,69 @@ public class KnowledgeDocumentController {
private final KnowledgeDocumentService knowledgeDocumentService; private final KnowledgeDocumentService knowledgeDocumentService;
private final FileTemplate fileTemplate; private final AskVectorStoreService askVectorStoreService;
/** /**
* 分页查询 * 分页查询
* @param page 分页对象 *
* @param page 分页对象
* @param knowledgeBaseId 知识库ID(必填) * @param knowledgeBaseId 知识库ID(必填)
* @param name 文档名称(非必填,模糊搜索) * @param name 文档名称(非必填,模糊搜索)
* @return 分页数据 * @return 分页数据
*/ */
@Operation(summary = "分页查询", description = "分页查询") @Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page") @GetMapping("/page")
public R<IPage<KnowledgeDocument>> getPage(Page page, public R<IPage<KnowledgeDocument>> getPage(Page page,
@Parameter(description = "知识库id") @RequestParam Long knowledgeBaseId, @Parameter(description = "知识库id") @RequestParam Long knowledgeBaseId,
@Parameter(description = "知识库名称") @RequestParam(required = false) String name) { @Parameter(description = "文档名称") @RequestParam(required = false) String name) {
LambdaQueryWrapper<KnowledgeDocument> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<KnowledgeDocument> wrapper = Wrappers.lambdaQuery();
// 知识库ID必填条件 // 知识库ID必填条件
wrapper.eq(KnowledgeDocument::getKnowledgeBaseId, knowledgeBaseId); wrapper.eq(KnowledgeDocument::getKnowledgeBaseId, knowledgeBaseId);
// 文档名称模糊搜索(非必填) // 文档名称模糊搜索(非必填)
if (StringUtils.hasText(name)) { if (StringUtils.hasText(name)) {
wrapper.like(KnowledgeDocument::getName, name.trim()); wrapper.like(KnowledgeDocument::getName, name.trim());
} }
// 按创建时间倒序排列 // 按创建时间倒序排列
wrapper.orderByDesc(KnowledgeDocument::getCreateTime); wrapper.orderByDesc(KnowledgeDocument::getCreateTime);
return R.ok(knowledgeDocumentService.page(page, wrapper)); return R.ok(knowledgeDocumentService.page(page, wrapper));
} }
/** // /**
* 通过id查询知识库文档 // * 通过id查询知识库文档
* @param id id // * @param id id
* @return R // * @return R
*/ // */
@Operation(summary = "通过id查询", description = "通过id查询") // @Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}") // @GetMapping("/{id}")
public R<KnowledgeDocument> getById(@PathVariable("id") Long id) { // public R<KnowledgeDocument> getById(@PathVariable("id") Long id) {
return R.ok(knowledgeDocumentService.getById(id)); // return R.ok(knowledgeDocumentService.getById(id));
} // }
/** /**
* 新增知识库文档 * 新增知识库文档
*
* @param knowledgeBaseId 知识库ID * @param knowledgeBaseId 知识库ID
* @param segmentResults 文档分段结果列表 * @param segmentResults 文档分段结果列表
* @return R * @return R
*/ */
@Operation(summary = "新增知识库文档", description = "保存文档分段结果到知识库") @Operation(summary = "新增知识库文档", description = "保存文档分段结果到知识库")
@PostMapping @PostMapping
public R<Boolean> save(@RequestParam Long knowledgeBaseId, public R<Boolean> save(@RequestParam Long knowledgeBaseId,
@RequestBody List<DocumentSegmentResult> segmentResults) { @RequestBody List<DocumentSegmentResult> segmentResults) {
// 校验知识库ID // 校验知识库ID
if (knowledgeBaseId == null || knowledgeBaseId <= 0) { if (knowledgeBaseId == null || knowledgeBaseId <= 0) {
return R.failed("知识库ID不能为空且必须大于0"); return R.failed("知识库ID不能为空且必须大于0");
} }
// 校验分段结果 // 校验分段结果
if (segmentResults == null || segmentResults.isEmpty()) { if (segmentResults == null || segmentResults.isEmpty()) {
return R.failed("文档分段结果不能为空"); return R.failed("文档分段结果不能为空");
} }
try { try {
boolean result = knowledgeDocumentService.saveSegmentResults(knowledgeBaseId, segmentResults); boolean result = knowledgeDocumentService.saveSegmentResults(knowledgeBaseId, segmentResults);
return R.ok(result); return R.ok(result);
...@@ -114,30 +121,38 @@ public class KnowledgeDocumentController { ...@@ -114,30 +121,38 @@ public class KnowledgeDocumentController {
} }
} }
/** // /**
* 修改知识库文档 // * 修改知识库文档
* @param knowledgeDocument 知识库文档 // * @param knowledgeDocument 知识库文档
* @return R // * @return R
*/ // */
@Operation(summary = "修改知识库文档", description = "修改知识库文档") // @Operation(summary = "修改知识库文档", description = "修改知识库文档")
@PutMapping // @PutMapping
public R<Boolean> updateById(@RequestBody KnowledgeDocument knowledgeDocument) { // public R<Boolean> updateById(@RequestBody KnowledgeDocument knowledgeDocument) {
return R.ok(knowledgeDocumentService.updateById(knowledgeDocument)); // return R.ok(knowledgeDocumentService.updateById(knowledgeDocument));
} // }
/** /**
* 通过id删除知识库文档 * 通过id删除知识库文档
* @param id id *
* @param ids
* @return R * @return R
*/ */
@Operation(summary = "通过id删除知识库文档", description = "通过id删除知识库文档") @Operation(summary = "批量知识库文档", description = "通过id删除知识库文档")
@DeleteMapping("/{id}") @DeleteMapping("/batch")
public R<Boolean> removeById(@PathVariable Long id) { @Transactional(rollbackFor = Exception.class)
return R.ok(knowledgeDocumentService.removeById(id)); public R<Boolean> removeById(@RequestBody List<Long> ids) {
ids.forEach(id -> {
knowledgeDocumentService.removeById(id);
askVectorStoreService.remove(Wrappers.lambdaQuery(AskVectorStore.class).eq(AskVectorStore::getDocumentId, id));
});
return R.ok(true);
} }
/** /**
* 文档分段处理 * 文档分段处理
*
* @param request 请求体 * @param request 请求体
* @return 文档分段结果列表 * @return 文档分段结果列表
*/ */
...@@ -156,6 +171,7 @@ public class KnowledgeDocumentController { ...@@ -156,6 +171,7 @@ public class KnowledgeDocumentController {
/** /**
* 检查文件类型是否支持 * 检查文件类型是否支持
*
* @param fileName 文件名 * @param fileName 文件名
* @return 是否支持 * @return 是否支持
*/ */
...@@ -163,19 +179,51 @@ public class KnowledgeDocumentController { ...@@ -163,19 +179,51 @@ public class KnowledgeDocumentController {
if (!StringUtils.hasText(fileName)) { if (!StringUtils.hasText(fileName)) {
return false; return false;
} }
String extension = fileName.toLowerCase(); String extension = fileName.toLowerCase();
return extension.endsWith(".pdf") || return extension.endsWith(".pdf") ||
extension.endsWith(".doc") || extension.endsWith(".doc") ||
extension.endsWith(".docx") || extension.endsWith(".docx") ||
extension.endsWith(".xls") || extension.endsWith(".xls") ||
extension.endsWith(".xlsx") || extension.endsWith(".xlsx") ||
extension.endsWith(".txt") || extension.endsWith(".txt") ||
extension.endsWith(".md") || extension.endsWith(".md") ||
extension.endsWith(".rtf") || extension.endsWith(".rtf") ||
extension.endsWith(".odt"); extension.endsWith(".odt");
} }
/**
* 修改文档启用状态
*
* @param documentId 文档ID
* @param isEnabled 启用状态(1:启用,0:禁用)
* @return 修改结果
*/
@Operation(summary = "修改文档启用状态", description = "修改指定文档的启用状态")
@PutMapping("/status/{documentId}")
public R<Boolean> updateDocumentStatus(@Parameter(description = "文档ID") @PathVariable Long documentId,
@Parameter(description = "启用状态(1:启用,0:禁用)") @RequestParam Integer isEnabled) {
// 参数校验
if (documentId == null || documentId <= 0) {
return R.failed("文档ID不能为空且必须大于0");
}
if (isEnabled == null || (isEnabled != 0 && isEnabled != 1)) {
return R.failed("启用状态参数无效,只能为0(禁用)或1(启用)");
}
try {
boolean result = knowledgeDocumentService.updateDocumentStatus(documentId, isEnabled);
if (result) {
return R.ok(true, "文档状态修改成功");
} else {
return R.failed("文档状态修改失败,请检查文档是否存在");
}
} catch (Exception e) {
log.error("修改文档状态异常,文档ID: {}, 状态: {}, 错误: {}", documentId, isEnabled, e.getMessage(), e);
return R.failed("修改文档状态失败:" + e.getMessage());
}
}
} }
\ No newline at end of file \ No newline at end of file
///*
// * Copyright (c) 2018-2025, lengleng All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice,
// * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// * notice, this list of conditions and the following disclaimer in the
// * documentation and/or other materials provided with the distribution.
// * Neither the name of the pig4cloud.com developer nor the names of its
// * contributors may be used to endorse or promote products derived from
// * this software without specific prior written permission.
// * Author: lengleng (wangiegie@gmail.com)
// */
//package com.ask.service;
//
//import com.ask.api.entity.GenDatasourceConf;
//import com.baomidou.mybatisplus.extension.service.IService;
//
//
//
///**
// * 数据源配置服务接口 提供数据源的增删改查及校验等功能
// *
// * @author lengleng
// * @date 2025/05/31
// */
//public interface GenDatasourceConfService extends IService<GenDatasourceConf> {
//
// /**
// * 保存数据源并加密
// * @param genDatasourceConf 数据源配置信息
// * @return 保存是否成功
// */
// Boolean saveDsByEnc(GenDatasourceConf genDatasourceConf);
//
// /**
// * 更新数据源
// * @param genDatasourceConf 数据源配置信息
// * @return 更新是否成功
// */
// Boolean updateDsByEnc(GenDatasourceConf genDatasourceConf);
//
// /**
// * 添加动态数据源
// * @param datasourceConf 数据源配置信息
// */
// void addDynamicDataSource(GenDatasourceConf datasourceConf);
//
// /**
// * 校验数据源配置是否有效
// * @param datasourceConf 数据源配置信息
// * @return true表示有效,false表示无效
// */
// Boolean checkDataSource(GenDatasourceConf datasourceConf);
//
// /**
// * 通过数据源ID删除数据源
// * @param dsIds 数据源ID数组
// * @return 删除是否成功
// */
// Boolean removeByDsId(Long[] dsIds);
//
//}
///*
// * Copyright (c) 2018-2025, lengleng All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice,
// * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// * notice, this list of conditions and the following disclaimer in the
// * documentation and/or other materials provided with the distribution.
// * Neither the name of the pig4cloud.com developer nor the names of its
// * contributors may be used to endorse or promote products derived from
// * this software without specific prior written permission.
// * Author: lengleng (wangiegie@gmail.com)
// */
//
//package com.ask.service;
//
//import com.ask.api.dto.TableDto;
//import com.ask.api.dto.TableParam;
//import com.ask.api.entity.GenTable;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.baomidou.mybatisplus.extension.service.IService;
//
//import java.util.List;
//
///**
// * 代码生成表服务接口
// *
// * @author lengleng
// * @date 2025/05/31
// */
//public interface GenTableService extends IService<GenTable> {
//
// /**
// * 查询对应数据源的表
// * @param page 分页信息
// * @param table 查询条件
// * @return 表
// */
// IPage<TableDto> queryTablePage(Page<TableDto> page, TableParam table);
//
//
// /**
// * 查询表ddl 语句
// * @param dsName 数据源名称
// * @param tableName 表名称
// * @return ddl 语句
// * @throws Exception
// */
// String queryTableDdl(String dsName, String tableName) throws Exception;
//
// /**
// * 查询数据源里面的全部表
// * @param dsName 数据源名称
// * @return table
// */
// List<String> queryTableList(String dsName);
//
// /**
// * 查询表的全部字段
// * @param dsName 数据源
// * @param tableName 表名称
// * @return column
// */
// List<String> queryTableColumn(String dsName, String tableName);
//
//}
...@@ -30,4 +30,13 @@ public interface KnowledgeDocumentService extends IService<KnowledgeDocument> { ...@@ -30,4 +30,13 @@ public interface KnowledgeDocumentService extends IService<KnowledgeDocument> {
*/ */
boolean saveSegmentResults(Long knowledgeBaseId, List<DocumentSegmentResult> segmentResults); boolean saveSegmentResults(Long knowledgeBaseId, List<DocumentSegmentResult> segmentResults);
/**
* 修改文档启用状态
* @param documentId 文档ID
* @param isEnabled 启用状态(1:启用,0:禁用)
* @return 修改结果
*/
boolean updateDocumentStatus(Long documentId, Integer isEnabled);
} }
\ No newline at end of file
///*
// * Copyright (c) 2018-2025, lengleng All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice,
// * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// * notice, this list of conditions and the following disclaimer in the
// * documentation and/or other materials provided with the distribution.
// * Neither the name of the pig4cloud.com developer nor the names of its
// * contributors may be used to endorse or promote products derived from
// * this software without specific prior written permission.
// * Author: lengleng (wangiegie@gmail.com)
// */
//package com.ask.service.impl;
//
//import com.ask.api.entity.GenDatasourceConf;
//import com.ask.mapper.GenDatasourceConfMapper;
//import com.ask.service.GenDatasourceConfService;
//import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
//import com.baomidou.dynamic.datasource.creator.DataSourceCreator;
//import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Service;
//
//import javax.sql.DataSource;
//import java.sql.Connection;
//import java.sql.DriverManager;
//import java.sql.SQLException;
//
///**
// * 数据源配置服务实现类
// *
// * <p>
// * 提供数据源的增删改查及校验功能,支持数据源密码加密存储
// * </p>
// *
// * @author lengleng
// * @date 2025/05/31
// */
//@Slf4j
//@Service
//@RequiredArgsConstructor
//public class GenDatasourceConfServiceImpl extends ServiceImpl<GenDatasourceConfMapper, GenDatasourceConf>
// implements GenDatasourceConfService {
//
// private final StringEncryptor stringEncryptor;
//
// private final DataSourceCreator hikariDataSourceCreator;
//
//
// /**
// * 保存数据源配置并进行加密处理
// * @param conf 数据源配置信息
// * @return 保存成功返回true,失败返回false
// */
// @Override
// public Boolean saveDsByEnc(GenDatasourceConf conf) {
// // 校验配置合法性
// if (!checkDataSource(conf)) {
// return Boolean.FALSE;
// }
//
// // 添加动态数据源
// addDynamicDataSource(conf);
//
// // 更新数据库配置
// conf.setPassword(stringEncryptor.encrypt(conf.getPassword()));
// this.baseMapper.insert(conf);
// return Boolean.TRUE;
// }
//
// /**
// * 更新加密数据源
// * @param conf 数据源配置信息
// * @return 更新成功返回true,失败返回false
// */
// @Override
// public Boolean updateDsByEnc(GenDatasourceConf conf) {
// if (!checkDataSource(conf)) {
// return Boolean.FALSE;
// }
// // 先移除
// DynamicRoutingDataSource dynamicRoutingDataSource = SpringContextHolder.getBean(DynamicRoutingDataSource.class);
// dynamicRoutingDataSource.removeDataSource(baseMapper.selectById(conf.getId()).getName());
//
// // 再添加
// addDynamicDataSource(conf);
//
// // 更新数据库配置
// if (StrUtil.isNotBlank(conf.getPassword())) {
// conf.setPassword(stringEncryptor.encrypt(conf.getPassword()));
// }
// this.baseMapper.updateById(conf);
// return Boolean.TRUE;
// }
//
// /**
// * 通过数据源ID删除数据源
// * @param dsIds 数据源ID数组
// * @return 删除是否成功
// */
// @Override
// public Boolean removeByDsId(Long[] dsIds) {
// DynamicRoutingDataSource dynamicRoutingDataSource = SpringContextHolder.getBean(DynamicRoutingDataSource.class);
// this.baseMapper.selectByIds(CollUtil.toList(dsIds))
// .forEach(ds -> dynamicRoutingDataSource.removeDataSource(ds.getName()));
// this.baseMapper.deleteByIds(CollUtil.toList(dsIds));
// return Boolean.TRUE;
// }
//
// /**
// * 添加动态数据源
// * @param conf 数据源配置信息
// */
// @Override
// public void addDynamicDataSource(GenDatasourceConf conf) {
// DataSourceProperty dataSourceProperty = new DataSourceProperty();
// dataSourceProperty.setPoolName(conf.getName());
// dataSourceProperty.setUrl(conf.getUrl());
// dataSourceProperty.setUsername(conf.getUsername());
// dataSourceProperty.setPassword(conf.getPassword());
// DataSource dataSource = hikariDataSourceCreator.createDataSource(dataSourceProperty);
//
// DynamicRoutingDataSource dynamicRoutingDataSource = SpringContextHolder.getBean(DynamicRoutingDataSource.class);
// dynamicRoutingDataSource.addDataSource(dataSourceProperty.getPoolName(), dataSource);
// }
//
// /**
// * 校验数据源配置是否有效
// * @param conf 数据源配置信息
// * @return 数据源配置是否有效,true表示有效
// * @throws RuntimeException 数据库连接失败时抛出异常
// */
// @Override
// public Boolean checkDataSource(GenDatasourceConf conf) {
// String url;
// // JDBC 配置形式
// if (DsConfTypeEnum.JDBC.getType().equals(conf.getConfType())) {
// url = conf.getUrl();
// }
// else if (DsJdbcUrlEnum.MSSQL.getDbName().equals(conf.getDsType())) {
// // 主机形式 sql server 特殊处理
// DsJdbcUrlEnum urlEnum = DsJdbcUrlEnum.get(conf.getDsType());
// url = String.format(urlEnum.getUrl(), conf.getHost(), conf.getPort(), conf.getDsName());
// }
// else {
// DsJdbcUrlEnum urlEnum = DsJdbcUrlEnum.get(conf.getDsType());
// url = String.format(urlEnum.getUrl(), conf.getHost(), conf.getPort(), conf.getDsName());
// }
//
// conf.setUrl(url);
//
// try (Connection connection = DriverManager.getConnection(url, conf.getUsername(), conf.getPassword())) {
// }
// catch (SQLException e) {
// log.error("数据源配置 {} , 获取链接失败", conf.getName(), e);
// throw new RuntimeException("数据库配置错误,链接失败");
// }
// return Boolean.TRUE;
// }
//
//}
///*
// * Copyright (c) 2018-2025, lengleng All rights reserved.
// *
// * Redistribution and use in source and binary forms, with or without
// * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice,
// * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// * notice, this list of conditions and the following disclaimer in the
// * documentation and/or other materials provided with the distribution.
// * Neither the name of the pig4cloud.com developer nor the names of its
// * contributors may be used to endorse or promote products derived from
// * this software without specific prior written permission.
// * Author: lengleng (wangiegie@gmail.com)
// */
//package com.ask.service.impl;
//
//import cn.hutool.core.util.EnumUtil;
//import cn.hutool.core.util.StrUtil;
//import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.pig4cloud.pig.ask.api.dto.TableDto;
//import com.pig4cloud.pig.ask.api.dto.TableParam;
//import com.pig4cloud.pig.ask.api.entity.GenTable;
//import com.pig4cloud.pig.ask.api.entity.GenTableColumnEntity;
//import com.pig4cloud.pig.ask.api.enums.AutoFillEnum;
//import com.pig4cloud.pig.ask.api.enums.BoolFillEnum;
//import com.pig4cloud.pig.ask.api.enums.CommonColumnFiledEnum;
//import com.pig4cloud.pig.ask.mapper.GenTableMapper;
//import com.pig4cloud.pig.ask.service.GenTableService;
//import com.pig4cloud.pig.ask.utils.DataSourceQueryUtils;
//import com.pig4cloud.pig.common.datasource.enums.DsJdbcUrlEnum;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.anyline.metadata.Column;
//import org.anyline.metadata.Table;
//import org.anyline.proxy.CacheProxy;
//import org.anyline.proxy.ServiceProxy;
//import org.jetbrains.annotations.NotNull;
//import org.springframework.stereotype.Service;
//
//import java.util.*;
//
///**
// * 代码生成表服务实现类
// *
// * @author lengleng
// * @date 2025/05/31
// */
//@Slf4j
//@Service
//@RequiredArgsConstructor
//public class GenTableServiceImpl extends ServiceImpl<GenTableMapper, GenTable> implements GenTableService {
// private final DataSourceQueryUtils dataSourceQueryUtils;
//
// /**
// * 查询表ddl 语句
// *
// * @param dsName 数据源名称
// * @param tableName 表名称
// * @return ddl 语句
// * @throws Exception
// */
// @Override
// public String queryTableDdl(String dsName, String tableName) throws Exception {
// // 手动切换数据源
// DynamicDataSourceContextHolder.push(dsName);
// Table table = ServiceProxy.metadata().table(tableName); // 获取表结构
// table.execute(false);// 不执行SQL
// ServiceProxy.ddl().create(table);
// return table.getDdl();// 返回创建表的DDL
// }
//
// /**
// * 查询表的全部字段
// *
// * @param dsName 数据源
// * @param tableName 表名称
// * @return column
// */
// @Override
// public List<String> queryTableColumn(String dsName, String tableName) {
// // 手动切换数据源
// DynamicDataSourceContextHolder.push(dsName);
// CacheProxy.clear();
// return ServiceProxy.metadata().columns(tableName).values().stream().map(Column::getName).toList();
// }
//
// /**
// * 查询对应数据源的表
// *
// * @param page 分页信息
// * @param table 查询条件
// * @return 表
// */
// @Override
// public IPage<TableDto> queryTablePage(Page<TableDto> page, TableParam table) {
// String sql = null;
// Map<String, Object> params = new HashMap<>();
// if (DsJdbcUrlEnum.MYSQL.getDbName().equals(table.getDbType())) {
// sql = "SELECT table_name,table_comment,create_time FROM information_schema.tables WHERE table_schema = (SELECT database()) AND table_type = 'BASE TABLE' ORDER BY table_name;";
// params.put("table_name", table.getTableName());
//
// } else if (DsJdbcUrlEnum.PG.getDbName().equals(table.getDbType())) {
// sql = """
// SELECT
// t.table_name,
// obj_description((t.table_schema || '.' || t.table_name)::regclass, 'pg_class') as table_comment
// FROM
// information_schema.tables t
// WHERE
// t.table_schema = current_schema()
// AND t.table_type = 'BASE TABLE'
// AND (:tableName IS NULL OR t.table_name ILIKE :tableName)
// ORDER BY
// t.table_name
// """;
// params.put("tableName",
// StrUtil.isBlank(table.getTableName()) ? null : "%" + table.getTableName() + "%");
// }
// if (StringUtils.isBlank(sql)) {
// return new Page<>(page.getCurrent(), page.getSize());
// }
//
// return dataSourceQueryUtils.executePageQuery(page,table.getDsName(),sql,TableDto.class);
// }
//
//
// /**
// * 查询数据源里面的全部表
// *
// * @param dsName 数据源名称
// * @return table
// */
// @Override
// public List<String> queryTableList(String dsName) {
// // 手动切换数据源
// DynamicDataSourceContextHolder.push(dsName);
// CacheProxy.clear();
// return ServiceProxy.metadata().tables().values().stream().map(Table::getName).toList();
// }
//
//
// /**
// * 获取表字段信息
// *
// * @param dsName 数据源信息
// * @param tableName 表名称
// * @param tableMetadata 表的元数据
// * @return list
// */
// private static @NotNull List<GenTableColumnEntity> getGenTableColumnEntities(String dsName, String tableName,
// Table tableMetadata) {
// List<GenTableColumnEntity> tableFieldList = new ArrayList<>();
// LinkedHashMap<String, Column> columns = tableMetadata.getColumns();
// columns.forEach((columnName, column) -> {
// GenTableColumnEntity genTableColumnEntity = new GenTableColumnEntity();
// genTableColumnEntity.setTableName(tableName);
// genTableColumnEntity.setDsName(dsName);
// genTableColumnEntity.setFieldName(column.getName());
// genTableColumnEntity.setFieldComment(column.getComment());
// genTableColumnEntity.setFieldType(column.getTypeName());
// genTableColumnEntity.setPrimaryPk(
// column.isPrimaryKey() == 1 ? BoolFillEnum.TRUE.getValue() : BoolFillEnum.FALSE.getValue());
// genTableColumnEntity.setAutoFill(AutoFillEnum.DEFAULT.name());
// genTableColumnEntity.setFormItem(BoolFillEnum.TRUE.getValue());
// genTableColumnEntity.setGridItem(BoolFillEnum.TRUE.getValue());
//
// // 审计字段处理
// if (EnumUtil.contains(CommonColumnFiledEnum.class, column.getName())) {
// CommonColumnFiledEnum commonColumnFiledEnum = CommonColumnFiledEnum.valueOf(column.getName());
// genTableColumnEntity.setFormItem(commonColumnFiledEnum.getFormItem());
// genTableColumnEntity.setGridItem(commonColumnFiledEnum.getGridItem());
// genTableColumnEntity.setAutoFill(commonColumnFiledEnum.getAutoFill());
// genTableColumnEntity.setSort(commonColumnFiledEnum.getSort());
// }
// tableFieldList.add(genTableColumnEntity);
// });
// return tableFieldList;
// }
//
//}
...@@ -2,12 +2,14 @@ package com.ask; ...@@ -2,12 +2,14 @@ package com.ask;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/** /**
* 启动类 * 启动类
* *
* @author YangKai * @author YangKai
*/ */
@EnableAsync
@SpringBootApplication @SpringBootApplication
public class AskDataAiApplication { public class AskDataAiApplication {
......
...@@ -39,10 +39,10 @@ spring: ...@@ -39,10 +39,10 @@ spring:
options: options:
model: qwen-plus model: qwen-plus
embedding: embedding:
base-url: http://localhost:11434/api/embeddings base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: sk-ae96ff281ff644c992843c64a711a950 api-key: sk-ae96ff281ff644c992843c64a711a950
options: options:
model: nomic-embed-text:latest model: text-embedding-v4
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置 mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置
...@@ -110,4 +110,4 @@ logging: ...@@ -110,4 +110,4 @@ logging:
file: file:
local: local:
enable: true enable: true
base-path: D:/app/upFiles base-path: /app/upFiles
\ No newline at end of file \ No newline at end of file
...@@ -39,10 +39,10 @@ spring: ...@@ -39,10 +39,10 @@ spring:
options: options:
model: qwen-plus model: qwen-plus
embedding: embedding:
base-url: http://localhost:11434/api/embeddings base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: sk-ae96ff281ff644c992843c64a711a950 api-key: sk-ae96ff281ff644c992843c64a711a950
options: options:
model: nomic-embed-text:latest model: text-embedding-v4
mybatis-plus: mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置 mapper-locations: classpath*:/mapper/*Mapper.xml # mapper文件位置
...@@ -110,4 +110,4 @@ logging: ...@@ -110,4 +110,4 @@ logging:
file: file:
local: local:
enable: true enable: true
base-path: D:/app/upFiles base-path: /app/upFiles
\ No newline at end of file \ No newline at end of file
...@@ -31,6 +31,9 @@ public class R<T> implements Serializable { ...@@ -31,6 +31,9 @@ public class R<T> implements Serializable {
public static <T> R<T> ok(T data) { public static <T> R<T> ok(T data) {
return new R<>(0, "success", data); return new R<>(0, "success", data);
} }
public static <T> R<T> ok(T data,String msg) {
return new R<>(0, msg, data);
}
public static <T> R<T> failed(String msg) { public static <T> R<T> failed(String msg) {
return new R<>(1, msg, null); return new R<>(1, msg, null);
......
...@@ -28,12 +28,14 @@ public class MybatisMetaObjectHandler implements MetaObjectHandler { ...@@ -28,12 +28,14 @@ public class MybatisMetaObjectHandler implements MetaObjectHandler {
this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
// 设置更新人(新增时也设置更新人) // 设置更新人(新增时也设置更新人)
this.strictInsertFill(metaObject, "updateBy", () -> "admin", String.class); this.strictInsertFill(metaObject, "updateBy", () -> "admin", String.class);
this.strictInsertFill(metaObject, "del_flag", () -> "0", String.class);
} }
@Override @Override
public void updateFill(MetaObject metaObject) { public void updateFill(MetaObject metaObject) {
log.debug("自动填充更新字段");
// 设置更新时间 // 设置更新时间
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
// 设置更新人 // 设置更新人
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment