新增内容管理数据到向量数据库的集成接口

This commit is contained in:
thinkgem
2025-03-11 15:27:11 +08:00
parent 132f814c2d
commit 186d18c160
9 changed files with 116 additions and 8 deletions

View File

@@ -44,6 +44,8 @@ public class ArticleService extends CrudService<ArticleDao, Article> {
@Autowired(required = false)
private ArticleIndexService articleIndexService;
@Autowired(required = false)
private ArticleVectorStore articleVectorStore;
@Autowired(required = false)
private PageCacheService pageCacheService;
private static final ExecutorService updateExpiredWeightThreadPool = new ThreadPoolExecutor(5, 20,
@@ -166,6 +168,10 @@ public class ArticleService extends CrudService<ArticleDao, Article> {
if (articleIndexService != null && Article.STATUS_NORMAL.equals(article.getStatus())) {
articleIndexService.save(article);
}
// 保存文章到向量数据库
if (articleVectorStore != null && Article.STATUS_NORMAL.equals(article.getStatus())) {
articleVectorStore.save(article);
}
// 清理首页、栏目和文章页面缓存
if (pageCacheService != null) {
pageCacheService.clearCache(article);
@@ -188,6 +194,14 @@ public class ArticleService extends CrudService<ArticleDao, Article> {
articleIndexService.delete(article);
}
}
// 保存文章到向量数据库
if (articleVectorStore != null) {
if (Article.STATUS_NORMAL.equals(article.getStatus())) {
articleVectorStore.save(article);
} else {
articleVectorStore.delete(article);
}
}
// 清理首页、栏目和文章页面缓存
if (pageCacheService != null) {
pageCacheService.clearCache(article);
@@ -221,6 +235,10 @@ public class ArticleService extends CrudService<ArticleDao, Article> {
if (articleIndexService != null) {
articleIndexService.delete(article);
}
// 保存文章到向量数据库
if (articleVectorStore != null) {
articleVectorStore.delete(article);
}
// 清理首页、栏目和文章页面缓存
if (pageCacheService != null) {
pageCacheService.clearCache(article);

View File

@@ -0,0 +1,36 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.modules.cms.service;
import com.jeesite.common.entity.Page;
import com.jeesite.modules.cms.entity.Article;
import java.util.Map;
/**
* 文章向量存储服务类
* @author ThinkGem
*/
public interface ArticleVectorStore {
/**
* 保存索引
* @author ThinkGem
*/
void save(Article article);
/**
* 删除索引
* @author ThinkGem
*/
void delete(Article article);
/**
* 重建向量库
* @author ThinkGem
*/
String rebuild(Article article);
}

View File

@@ -27,6 +27,8 @@ public class CategoryService extends TreeService<CategoryDao, Category> {
@Autowired(required = false)
private ArticleIndexService articleIndexService;
@Autowired(required = false)
private ArticleVectorStore articleVectorStore;
@Autowired(required = false)
private PageCacheService pageCacheService;
/**
@@ -125,4 +127,15 @@ public class CategoryService extends TreeService<CategoryDao, Category> {
return articleIndexService.rebuild(new Article(category));
}
/**
* 重建向量数据库
* @author ThinkGem
*/
public String rebuildVectorStore(Category category) {
if (articleVectorStore == null) {
return text("您好,系统未安装全文检索模块");
}
return articleVectorStore.rebuild(new Article(category));
}
}

View File

@@ -27,6 +27,8 @@ public class SiteService extends CrudService<SiteDao, Site> {
@Autowired(required = false)
private ArticleIndexService articleIndexService;
@Autowired(required = false)
private ArticleVectorStore articleVectorStore;
@Autowired(required = false)
private PageCacheService pageCacheService;
/**
@@ -120,5 +122,16 @@ public class SiteService extends CrudService<SiteDao, Site> {
}
return articleIndexService.rebuild(new Article(new Category(site)));
}
/**
* 重建向量数据库
* @author ThinkGem
*/
public String rebuildVectorStore(Site site) {
if (articleVectorStore == null) {
return text("您好系统未安装内容管理AI模块");
}
return articleVectorStore.rebuild(new Article(new Category(site)));
}
}

View File

@@ -256,6 +256,17 @@ public class CategoryController extends BaseController {
return renderResult(Global.TRUE, categoryService.rebuildIndex(category));
}
/**
* 重建向量数据库
* @author ThinkGem
*/
@RequiresPermissions("cms:category:rebuildVectorStore")
@ResponseBody
@RequestMapping(value = "rebuildVectorStore")
public String rebuildVectorStore(Category category) {
return renderResult(Global.TRUE, categoryService.rebuildVectorStore(category));
}
/**
* 获取树结构数据
* @param excludeCode 排除的Code

View File

@@ -8,12 +8,12 @@ import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.common.web.CookieUtils;
import com.jeesite.modules.cms.entity.Site;
import com.jeesite.modules.cms.service.FileTempleteService;
import com.jeesite.modules.cms.service.SiteService;
import com.jeesite.modules.sys.utils.CorpUtils;
import com.jeesite.modules.sys.utils.UserUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@@ -24,8 +24,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
@@ -144,6 +142,17 @@ public class SiteController extends BaseController {
public String rebuildIndex(Site site) {
return renderResult(Global.TRUE, siteService.rebuildIndex(site));
}
/**
* 重建向量数据库
* @author ThinkGem
*/
@RequiresPermissions("cms:site:rebuildVectorStore")
@ResponseBody
@RequestMapping(value = "rebuildVectorStore")
public String rebuildVectorStore(Site site) {
return renderResult(Global.TRUE, siteService.rebuildVectorStore(site));
}
/**
* 选择站点

View File

@@ -20,5 +20,7 @@ j2cache:
#spring:
# elasticsearch:
# enabled: true
# uris: http://Win11:9200
# uris: http://127.0.0.1:9200
# connection-timeout: 120s
# username: elastic
# password: elastic

View File

@@ -85,7 +85,7 @@ $('#dataGrid').dataGrid({
{header:'${text("展现方式")}', name:'showModes', index:'a.show_modes', width:150, fixed:true, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel("#{@DictUtils.getDictListJson('cms_show_modes')}", val, '未知', true);
}},
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
{header:'${text("操作")}', name:'actions', width:180, formatter: function(val, obj, row, act){
var actions = [];
//# if(hasPermi('cms:category:edit')){
actions.push('<a href="${ctx}/cms/category/form?categoryCode='+row.categoryCode+'" class="btnList" title="${text("编辑栏目表")}"><i class="fa fa-pencil"></i></a>&nbsp;');
@@ -98,7 +98,10 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/cms/category/delete?categoryCode='+row.categoryCode+'" class="btnList" title="${text("删除栏目表")}" data-confirm="${text("确认要删除该栏目表及所有子栏目表吗?")}" data-deltreenode="'+row.id+'"><i class="fa fa-trash-o"></i></a>&nbsp;');
actions.push('<a href="${ctx}/cms/category/form?parentCode='+row.id+'&site.siteCode=${category.site.siteCode}" class="btnList" title="${text("新增下级栏目表")}"><i class="fa fa-plus-square"></i></a>&nbsp;');
//# if(hasPermi('cms:category:rebuildIndex')){
actions.push('<a href="${ctx}/cms/category/rebuildIndex?categoryCode='+row.categoryCode+'" class="btnList" title="${text("重建该栏目索引")}" data-confirm="${text("确认重建该栏目文章索引吗")}"><i class="fa fa-crosshairs"></i></a>&nbsp;');
actions.push('<a href="${ctx}/cms/category/rebuildIndex?categoryCode='+row.categoryCode+'" class="btnList" title="${text("重建该栏目索引")}" data-confirm="${text("确认重建该栏目文章索引吗")}"><i class="fa fa-crosshairs"></i></a>&nbsp;');
//# }
//# if(hasPermi('cms:category:rebuildVectorStore')){
actions.push('<a href="${ctx}/cms/category/rebuildVectorStore?categoryCode='+row.categoryCode+'" class="btnList" title="${text("重建该栏目向量数据库")}" data-confirm="${text("确认重建该栏目文章向量数据库吗")}"><i class="fa fa-database"></i></a>&nbsp;');
//# }
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctxFront}/list-'+row.categoryCode+'" target="_blank" title="${text("访问栏目")}"><i class="fa fa-globe"></i></a>&nbsp;');

View File

@@ -67,7 +67,7 @@ $('#dataGrid').dataGrid({
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_search_status')}", val, '${text("未知")}', true);
}},
{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
{header:'${text("操作")}', name:'actions', width:160, formatter: function(val, obj, row, act){
var actions = [];
//# if(hasPermi('cms:site:edit')){
actions.push('<a href="${ctx}/cms/site/form?siteCode='+row.siteCode+'" class="btnList" title="${text("编辑站点")}"><i class="fa fa-pencil"></i></a>&nbsp;');
@@ -81,6 +81,9 @@ $('#dataGrid').dataGrid({
//# if(hasPermi('cms:site:rebuildIndex')){
actions.push('<a href="${ctx}/cms/site/rebuildIndex?siteCode='+row.siteCode+'" class="btnList" title="${text("重建该站点索引")}" data-confirm="${text("确认重建该站点文章索引吗")}"><i class="fa fa-crosshairs"></i></a>&nbsp;');
//# }
//# if(hasPermi('cms:site:rebuildVectorStore')){
actions.push('<a href="${ctx}/cms/site/rebuildVectorStore?siteCode='+row.siteCode+'" class="btnList" title="${text("重建该站点向量数据库")}" data-confirm="${text("确认重建该站点文章向量数据库吗")}"><i class="fa fa-database"></i></a>&nbsp;');
//# }
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctxFront}/index-'+row.siteCode+'" target="_blank" title="${text("访问站点")}"><i class="fa fa-globe"></i></a>&nbsp;');
}