5 Commits

Author SHA1 Message Date
v-zhangjc9
60477f99f5 fix(ai-web): 修复错别字 2025-06-17 17:43:18 +08:00
v-zhangjc9
565c530dd5 feat(ai-web): 知识库增加描述 2025-06-17 17:19:04 +08:00
v-zhangjc9
5130885033 fix(ai-web): 改正包名 2025-06-17 16:18:38 +08:00
v-zhangjc9
8e6463845b feat(ai-web): 开启gzip 2025-06-17 16:16:01 +08:00
v-zhangjc9
e89bffe289 feat(ai-web): 增加Feedback详情展示和处理情况确认 2025-06-17 16:15:42 +08:00
17 changed files with 296 additions and 74 deletions

View File

@@ -1,11 +1,11 @@
CREATE TABLE `service_ai_feedback` CREATE TABLE `service_ai_feedback`
( (
`id` bigint NOT NULL, `id` bigint NOT NULL,
`source` longtext NOT NULL, `source` longtext NOT NULL,
`analysis_short` longtext, `conclusion` longtext,
`analysis` longtext, `analysis` longtext,
`pictures` longtext, `pictures` longtext,
`status` varchar(50) NOT NULL DEFAULT 'ANALYSIS_PROCESSING', `status` varchar(50) NOT NULL DEFAULT 'ANALYSIS_PROCESSING',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP `modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) DEFAULT CHARSET = utf8mb4; ) DEFAULT CHARSET = utf8mb4;

View File

@@ -3,6 +3,7 @@ CREATE TABLE `service_ai_knowledge`
`id` bigint NOT NULL, `id` bigint NOT NULL,
`vector_source_id` varchar(100) NOT NULL, `vector_source_id` varchar(100) NOT NULL,
`name` varchar(100) NOT NULL, `name` varchar(100) NOT NULL,
`description` longtext NOT NULL,
`strategy` varchar(10) NOT NULL, `strategy` varchar(10) NOT NULL,
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.ai.web.controller.caht; package com.lanyuanxiaoyao.service.ai.web.controller.chat;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.lanyuanxiaoyao.service.ai.web.configuration.Prompts; import com.lanyuanxiaoyao.service.ai.web.configuration.Prompts;

View File

@@ -45,12 +45,28 @@ public class FeedbackController {
feedbackService.remove(id); feedbackService.remove(id);
} }
@GetMapping("reanalysis")
public void reanalysis(@RequestParam("id") Long id) {
feedbackService.reanalysis(id);
}
@PostMapping("conclude")
public void conclude(@RequestBody ConcludeItem item) {
feedbackService.updateConclusion(item.getId(), item.getConclusion());
}
@Data @Data
public static final class CreateItem { public static final class CreateItem {
private String source; private String source;
private ImmutableList<Long> pictures; private ImmutableList<Long> pictures;
} }
@Data
public static final class ConcludeItem {
private Long id;
private String conclusion;
}
@Data @Data
public static final class ListItem { public static final class ListItem {
private Long id; private Long id;
@@ -58,7 +74,7 @@ public class FeedbackController {
private ImmutableList<String> pictures; private ImmutableList<String> pictures;
private Feedback.Status status; private Feedback.Status status;
private String analysis; private String analysis;
private String analysisShort; private String conclusion;
public ListItem(FileStoreProperties fileStoreProperties, Feedback feedback) { public ListItem(FileStoreProperties fileStoreProperties, Feedback feedback) {
this.id = feedback.getId(); this.id = feedback.getId();
@@ -67,7 +83,7 @@ public class FeedbackController {
.collect(id -> StrUtil.format("{}/upload/download/{}", fileStoreProperties.getDownloadPrefix(), id)); .collect(id -> StrUtil.format("{}/upload/download/{}", fileStoreProperties.getDownloadPrefix(), id));
this.status = feedback.getStatus(); this.status = feedback.getStatus();
this.analysis = feedback.getAnalysis(); this.analysis = feedback.getAnalysis();
this.analysisShort = feedback.getAnalysisShort(); this.conclusion = feedback.getConclusion();
} }
} }
} }

View File

@@ -37,9 +37,18 @@ public class KnowledgeBaseController {
@PostMapping("add") @PostMapping("add")
public void add( public void add(
@RequestParam("name") String name, @RequestParam("name") String name,
@RequestParam("description") String description,
@RequestParam("strategy") String strategy @RequestParam("strategy") String strategy
) throws ExecutionException, InterruptedException { ) throws ExecutionException, InterruptedException {
knowledgeBaseService.add(name, strategy); knowledgeBaseService.add(name, description, strategy);
}
@PostMapping("update_description")
public void updateDescription(
@RequestParam("id") Long id,
@RequestParam("description") String description
) {
knowledgeBaseService.updateDescription(id, description);
} }
@GetMapping("name") @GetMapping("name")

View File

@@ -7,9 +7,9 @@ import org.eclipse.collections.api.list.ImmutableList;
public class Feedback { public class Feedback {
private Long id; private Long id;
private String source; private String source;
private String analysisShort;
private String analysis;
private ImmutableList<Long> pictureIds; private ImmutableList<Long> pictureIds;
private String analysis;
private String conclusion;
private Status status; private Status status;
private Long createdTime; private Long createdTime;
private Long modifiedTime; private Long modifiedTime;

View File

@@ -11,6 +11,7 @@ public class Knowledge {
private Long id; private Long id;
private Long vectorSourceId; private Long vectorSourceId;
private String name; private String name;
private String description;
private String strategy; private String strategy;
private Long createdTime; private Long createdTime;
private Long modifiedTime; private Long modifiedTime;

View File

@@ -11,6 +11,7 @@ public class KnowledgeVO {
private Long id; private Long id;
private Long vectorSourceId; private Long vectorSourceId;
private String name; private String name;
private String description;
private String strategy; private String strategy;
private Long size; private Long size;
private Long points; private Long points;

View File

@@ -26,12 +26,12 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class FeedbackService { public class FeedbackService {
public static final String FEEDBACK_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_feedback"; public static final String FEEDBACK_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_feedback";
public static final String[] FEEDBACK_COLUMNS = new String[]{"id", "source", "analysis_short", "analysis", "pictures", "status", "created_time", "modified_time"}; public static final String[] FEEDBACK_COLUMNS = new String[]{"id", "source", "conclusion", "analysis", "pictures", "status", "created_time", "modified_time"};
private static final RowMapper<Feedback> feedbackMapper = (rs, row) -> { private static final RowMapper<Feedback> feedbackMapper = (rs, row) -> {
Feedback feedback = new Feedback(); Feedback feedback = new Feedback();
feedback.setId(rs.getLong(1)); feedback.setId(rs.getLong(1));
feedback.setSource(rs.getString(2)); feedback.setSource(rs.getString(2));
feedback.setAnalysisShort(rs.getString(3)); feedback.setConclusion(rs.getString(3));
feedback.setAnalysis(rs.getString(4)); feedback.setAnalysis(rs.getString(4));
feedback.setPictureIds( feedback.setPictureIds(
StrUtil.isBlank(rs.getString(5)) StrUtil.isBlank(rs.getString(5))
@@ -92,20 +92,32 @@ public class FeedbackService {
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateAnalysis(Long id, String analysis, String analysisShort) { public void updateAnalysis(Long id, String analysis) {
Assert.notNull(id, "ID cannot be null"); Assert.notNull(id, "ID cannot be null");
template.update( template.update(
SqlBuilder.update(FEEDBACK_TABLE_NAME) SqlBuilder.update(FEEDBACK_TABLE_NAME)
.set("analysis", "?") .set("analysis", "?")
.addSet("analysis_short", "?")
.whereEq("id", "?") .whereEq("id", "?")
.precompileSql(), .precompileSql(),
analysis, analysis,
analysisShort,
id id
); );
} }
@Transactional(rollbackFor = Exception.class)
public void updateConclusion(Long id, String conclusion) {
Assert.notNull(id, "ID cannot be null");
template.update(
SqlBuilder.update(FEEDBACK_TABLE_NAME)
.set("conclusion", "?")
.whereEq("id", "?")
.precompileSql(),
conclusion,
id
);
updateStatus(id, Feedback.Status.FINISHED);
}
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void updateStatus(Long id, Feedback.Status status) { public void updateStatus(Long id, Feedback.Status status) {
Assert.notNull(id, "ID cannot be null"); Assert.notNull(id, "ID cannot be null");
@@ -140,4 +152,9 @@ public class FeedbackService {
.build() .build()
); );
} }
@Transactional(rollbackFor = Exception.class)
public void reanalysis(Long id) {
updateStatus(id, Feedback.Status.ANALYSIS_PROCESSING);
}
} }

View File

@@ -9,7 +9,6 @@ import com.lanyuanxiaoyao.service.ai.web.entity.vo.KnowledgeVO;
import com.lanyuanxiaoyao.service.common.Constants; import com.lanyuanxiaoyao.service.common.Constants;
import io.qdrant.client.QdrantClient; import io.qdrant.client.QdrantClient;
import io.qdrant.client.grpc.Collections; import io.qdrant.client.grpc.Collections;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -32,14 +31,16 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
public class KnowledgeBaseService { public class KnowledgeBaseService {
public static final String KNOWLEDGE_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_knowledge"; public static final String KNOWLEDGE_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_knowledge";
public static final String[] KNOWLEDGE_COLUMNS = new String[]{"id", "vector_source_id", "name", "description", "strategy", "created_time", "modified_time"};
private static final RowMapper<Knowledge> knowledgeMapper = (rs, row) -> { private static final RowMapper<Knowledge> knowledgeMapper = (rs, row) -> {
Knowledge knowledge = new Knowledge(); Knowledge knowledge = new Knowledge();
knowledge.setId(rs.getLong(1)); knowledge.setId(rs.getLong(1));
knowledge.setVectorSourceId(rs.getLong(2)); knowledge.setVectorSourceId(rs.getLong(2));
knowledge.setName(rs.getString(3)); knowledge.setName(rs.getString(3));
knowledge.setStrategy(rs.getString(4)); knowledge.setDescription(rs.getString(4));
knowledge.setCreatedTime(rs.getTimestamp(5).getTime()); knowledge.setStrategy(rs.getString(5));
knowledge.setModifiedTime(rs.getTimestamp(6).getTime()); knowledge.setCreatedTime(rs.getTimestamp(6).getTime());
knowledge.setModifiedTime(rs.getTimestamp(7).getTime());
return knowledge; return knowledge;
}; };
private final JdbcTemplate template; private final JdbcTemplate template;
@@ -56,7 +57,7 @@ public class KnowledgeBaseService {
public Knowledge get(Long id) { public Knowledge get(Long id) {
return template.queryForObject( return template.queryForObject(
SqlBuilder.select("id", "vector_source_id", "name", "strategy", "created_time", "modified_time") SqlBuilder.select(KNOWLEDGE_COLUMNS)
.from(KNOWLEDGE_TABLE_NAME) .from(KNOWLEDGE_TABLE_NAME)
.whereEq("id", "?") .whereEq("id", "?")
.precompileSql(), .precompileSql(),
@@ -66,7 +67,7 @@ public class KnowledgeBaseService {
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void add(String name, String strategy) throws ExecutionException, InterruptedException { public void add(String name, String description, String strategy) throws ExecutionException, InterruptedException {
Integer count = template.queryForObject( Integer count = template.queryForObject(
SqlBuilder.select("count(*)") SqlBuilder.select("count(*)")
.from(KNOWLEDGE_TABLE_NAME) .from(KNOWLEDGE_TABLE_NAME)
@@ -82,13 +83,14 @@ public class KnowledgeBaseService {
long id = SnowflakeId.next(); long id = SnowflakeId.next();
long vectorSourceId = SnowflakeId.next(); long vectorSourceId = SnowflakeId.next();
template.update( template.update(
SqlBuilder.insertInto(KNOWLEDGE_TABLE_NAME, "id", "vector_source_id", "name", "strategy") SqlBuilder.insertInto(KNOWLEDGE_TABLE_NAME, "id", "vector_source_id", "name", "description", "strategy")
.values() .values()
.addValue("?", "?", "?", "?") .addValue("?", "?", "?", "?", "?")
.precompileSql(), .precompileSql(),
id, id,
vectorSourceId, vectorSourceId,
name, name,
description,
strategy strategy
); );
client.createCollectionAsync( client.createCollectionAsync(
@@ -100,6 +102,18 @@ public class KnowledgeBaseService {
).get(); ).get();
} }
@Transactional(rollbackFor = Exception.class)
public void updateDescription(Long id, String description) {
template.update(
SqlBuilder.update(KNOWLEDGE_TABLE_NAME)
.set("description", "?")
.whereEq("id", "?")
.precompileSql(),
description,
id
);
}
public String getName(Long id) { public String getName(Long id) {
return template.queryForObject( return template.queryForObject(
SqlBuilder.select("name") SqlBuilder.select("name")
@@ -113,7 +127,7 @@ public class KnowledgeBaseService {
public ImmutableList<KnowledgeVO> list() { public ImmutableList<KnowledgeVO> list() {
return template.query( return template.query(
SqlBuilder.select("id", "vector_source_id", "name", "strategy", "created_time", "modified_time") SqlBuilder.select(KNOWLEDGE_COLUMNS)
.from(KNOWLEDGE_TABLE_NAME) .from(KNOWLEDGE_TABLE_NAME)
.orderByDesc("created_time") .orderByDesc("created_time")
.build(), .build(),
@@ -127,6 +141,7 @@ public class KnowledgeBaseService {
vo.setId(knowledge.getId()); vo.setId(knowledge.getId());
vo.setVectorSourceId(knowledge.getVectorSourceId()); vo.setVectorSourceId(knowledge.getVectorSourceId());
vo.setName(knowledge.getName()); vo.setName(knowledge.getName());
vo.setDescription(knowledge.getDescription());
vo.setPoints(info.getPointsCount()); vo.setPoints(info.getPointsCount());
vo.setSegments(info.getSegmentsCount()); vo.setSegments(info.getSegmentsCount());
vo.setStatus(info.getStatus().name()); vo.setStatus(info.getStatus().name());
@@ -165,7 +180,7 @@ public class KnowledgeBaseService {
String text, String text,
Integer limit, Integer limit,
Double threshold Double threshold
) throws ExecutionException, InterruptedException, IOException { ) throws ExecutionException, InterruptedException {
Knowledge knowledge = get(id); Knowledge knowledge = get(id);
Boolean exists = client.collectionExistsAsync(String.valueOf(knowledge.getVectorSourceId())).get(); Boolean exists = client.collectionExistsAsync(String.valueOf(knowledge.getVectorSourceId())).get();
if (!exists) { if (!exists) {
@@ -182,13 +197,6 @@ public class KnowledgeBaseService {
.similarityThreshold(threshold) .similarityThreshold(threshold)
.build() .build()
); );
// 如果只是一个知识库的话似乎没有什么rerank的必要...
/* List<org.noear.solon.ai.rag.Document> rerankDocuments = rerankingModel.rerank(
text,
documents.stream()
.map(doc -> new org.noear.solon.ai.rag.Document(doc.getId(), doc.getText(), doc.getMetadata(), doc.getScore()))
.toList()
); */
return Lists.immutable.ofAll(documents) return Lists.immutable.ofAll(documents)
.collect(Document::getText); .collect(Document::getText);
} }

View File

@@ -156,7 +156,7 @@ public class FeedbackNodes {
if (StrUtil.isBlank(optimizedSource)) { if (StrUtil.isBlank(optimizedSource)) {
log.warn("Optimized source is blank"); log.warn("Optimized source is blank");
} }
context.setOptimizedSource(optimizedSource); context.setOptimizedSource(StrUtil.trim(optimizedSource));
} }
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "feedback_suggest", nodeName = "大模型建议", nodeType = NodeTypeEnum.COMMON) @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "feedback_suggest", nodeName = "大模型建议", nodeType = NodeTypeEnum.COMMON)
@@ -165,29 +165,39 @@ public class FeedbackNodes {
Feedback feedback = context.getFeedback(); Feedback feedback = context.getFeedback();
ChatClient client = chatClientBuilder.build(); ChatClient client = chatClientBuilder.build();
String analysis = client.prompt() String analysis = client.prompt()
// language=TEXT
.system(""" .system("""
你是一名专业的IT系统运维工程师,对于用户输入的报障信息,你会给出专业的意见 你是一名专业的IT系统运维工程师。针对用户输入的报障信息,严格遵循以下步骤:
1. 提取关键要素: 精准识别报障信息中的关键要素(如系统/设备名称、故障现象、错误信息、时间地点、影响范围、用户操作步骤等)。
2. 分析诊断: 基于提取的要素,运用运维专业知识,分析潜在原因,并提出优先级高、可操作性强的排障建议或初步诊断方向。
3. 输出专业意见:
内容要求: 意见必须包含明确的行动步骤如检查XX日志、验证XX配置、重启XX服务、联系XX团队、潜在风险提示及预期效果。
表达要求: 使用清晰、简洁、专业的技术术语,避免使用推测性语言或不确定词汇(如“可能”、“大概”、“也许”)。
格式要求: 直接输出意见内容,避免添加引导语(如“我的建议是”、“根据报障信息”等)。
""") """)
.user(context.getOptimizedSource()) .user(context.getOptimizedSource())
.call() .call()
.content(); .content();
feedback.setAnalysis(analysis); feedback.setAnalysis(StrUtil.trim(analysis));
Assert.notBlank(analysis, "Analysis cannot be blank"); Assert.notBlank(analysis, "Analysis cannot be blank");
String analysisShort = client.prompt() String conclusion = client.prompt()
// language=TEXT
.system(""" .system("""
你是一名专业的文字编辑,对用户输入的内容,用一段话总结内容 你是一名专业的文字编辑。严格按以下要求处理用户输入:
""") 核心逻辑: 用一段话精准总结输入内容的核心信息,确保涵盖所有关键点。禁止虚构、扩展或添加原文不存在的信息。
输出规范: 仅输出一段总结文本。禁止分点、分段、使用Markdown格式如着重、- 或 1. 等列表符号)或添加任何无关引导语(如“总结如下”、“该总结指出”、“本文总结”等)。直接给出总结文本。""")
.user(analysis) .user(analysis)
.call() .call()
.content(); .content();
feedback.setAnalysisShort(analysisShort); feedback.setConclusion(StrUtil.trim(conclusion));
} }
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "feedback_save", nodeName = "保存分析内容", nodeType = NodeTypeEnum.COMMON) @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "feedback_save", nodeName = "保存分析内容", nodeType = NodeTypeEnum.COMMON)
public void saveFeedback(NodeComponent node) { public void saveFeedback(NodeComponent node) {
FeedbackContext context = node.getContextBean(FeedbackContext.class); FeedbackContext context = node.getContextBean(FeedbackContext.class);
Feedback feedback = context.getFeedback(); Feedback feedback = context.getFeedback();
feedbackService.updateAnalysis(feedback.getId(), feedback.getAnalysis(), feedback.getAnalysisShort()); feedbackService.updateAnalysis(feedback.getId(), feedback.getAnalysis());
feedbackService.updateConclusion(feedback.getId(), feedback.getConclusion());
feedbackService.updateStatus(feedback.getId(), Feedback.Status.ANALYSIS_SUCCESS); feedbackService.updateStatus(feedback.getId(), Feedback.Status.ANALYSIS_SUCCESS);
} }
} }

View File

@@ -1,3 +1,6 @@
server:
compression:
enabled: true
spring: spring:
application: application:
name: service-ai-web name: service-ai-web
@@ -36,4 +39,4 @@ spring:
liteflow: liteflow:
rule-source: liteflow.xml rule-source: liteflow.xml
print-banner: false print-banner: false
check-node-exists: false check-node-exists: false

View File

@@ -4,6 +4,8 @@ import {amisRender, commonInfo, crudCommonOptions, mappingField, mappingItem} fr
const FeedbackDiv = styled.div` const FeedbackDiv = styled.div`
.feedback-list-images { .feedback-list-images {
margin-top: 10px;
.antd-Img-container { .antd-Img-container {
width: 32px; width: 32px;
height: 32px; height: 32px;
@@ -84,17 +86,24 @@ const Feedback: React.FC = () => {
width: 150, width: 150,
}, },
{ {
name: 'source',
label: '故障描述', label: '故障描述',
}, type: 'flex',
{ direction: 'column',
name: 'pictures', items: [
label: '相关截图', {
width: 200, type: 'tpl',
className: 'feedback-list-images', className: 'white-space-pre',
type: 'images', tpl: '${source}',
enlargeAble: true, },
enlargeWithGallary: true, {
className: 'feedback-list-images',
type: 'images',
enlargeAble: true,
enlargeWithGallary: true,
source: '${pictures}',
showToolbar: true,
},
],
}, },
{ {
label: '状态', label: '状态',
@@ -105,9 +114,107 @@ const Feedback: React.FC = () => {
{ {
type: 'operation', type: 'operation',
label: '操作', label: '操作',
width: 150, width: 200,
buttons: [ buttons: [
{ {
visibleOn: '${status === \'ANALYSIS_SUCCESS\'}',
type: 'action',
label: '重新分析',
level: 'link',
size: 'sm',
actionType: 'ajax',
api: {
method: 'get',
url: `${commonInfo.baseAiUrl}/feedback/reanalysis`,
data: {
id: '${id}',
},
},
confirmText: '确认执行重新分析?',
confirmTitle: '重新分析',
},
{
disabledOn: '${status === \'ANALYSIS_PROCESSING\'}',
type: 'action',
label: '详情',
level: 'link',
size: 'sm',
actionType: 'dialog',
dialog: {
title: '报障详情',
size: 'lg',
closeOnOutside: true,
actions: [
{
visibleOn: '${status !== \'FINISHED\'}',
type: 'action',
actionType: 'close',
label: '取消',
},
{
visibleOn: '${status !== \'FINISHED\'}',
type: 'submit',
label: '确认',
level: 'primary',
},
],
body: {
debug: commonInfo.debug,
type: 'form',
mode: 'normal',
api: {
method: 'post',
url: `${commonInfo.baseAiUrl}/feedback/conclude`,
data: {
id: '${id}',
conclusion: '${conclusion|default:undefined}',
},
},
body: [
{
type: 'textarea',
name: 'source',
label: '报障描述',
static: true,
},
{
type: 'control',
name: 'pictures',
label: '相关截图',
body: {
type: 'images',
enlargeAble: true,
enlargeWithGallary: true,
showToolbar: true,
},
},
{
type: 'control',
name: 'analysis',
label: 'AI辅助分析',
body: {
type: 'markdown',
},
},
{
visibleOn: '${status !== \'FINISHED\'}',
type: 'textarea',
name: 'conclusion',
label: '结论',
},
{
visibleOn: '${status === \'FINISHED\'}',
type: 'textarea',
name: 'conclusion',
label: '结论',
static: true,
},
],
},
},
},
{
disabledOn: '${status === \'ANALYSIS_PROCESSING\'}',
type: 'action', type: 'action',
label: '删除', label: '删除',
className: 'text-danger hover:text-red-600', className: 'text-danger hover:text-red-600',
@@ -121,8 +228,8 @@ const Feedback: React.FC = () => {
id: '${id}', id: '${id}',
}, },
}, },
confirmText: '确认删除',
confirmTitle: '删除', confirmTitle: '删除',
confirmText: '删除后将无法恢复,确认删除?',
}, },
], ],
}, },

View File

@@ -50,12 +50,20 @@ const Knowledge: React.FC = () => {
type: 'input-text', type: 'input-text',
name: 'name', name: 'name',
label: '名称', label: '名称',
required: true,
},
{
type: 'textarea',
name: 'description',
label: '描述',
required: true,
}, },
{ {
type: 'select', type: 'select',
name: 'strategy', name: 'strategy',
label: '类型', label: '类型',
value: 'Cosine', value: 'Cosine',
required: true,
options: [ options: [
{ {
label: '文本', label: '文本',
@@ -77,6 +85,11 @@ const Knowledge: React.FC = () => {
{ {
name: 'name', name: 'name',
label: '名称', label: '名称',
width: 200,
},
{
name: 'description',
label: '描述',
}, },
{ {
label: '类型', label: '类型',
@@ -99,8 +112,41 @@ const Knowledge: React.FC = () => {
{ {
type: 'operation', type: 'operation',
label: '操作', label: '操作',
width: 150, width: 200,
buttons: [ buttons: [
{
type: 'action',
label: '更新',
level: 'link',
size: 'sm',
actionType: 'dialog',
dialog: {
title: '更新描述',
body: {
debug: commonInfo.debug,
type: 'form',
api: {
method: 'post',
url: `${commonInfo.baseAiUrl}/knowledge/update_description`,
dataType: 'form',
},
mode: 'normal',
body: [
{
type: 'hidden',
name: "id",
// value: '${id}',
},
{
type: 'textarea',
name: 'description',
label: '描述',
required: true,
}
]
}
}
},
{ {
type: 'action', type: 'action',
label: '详情', label: '详情',

View File

@@ -1,19 +1,21 @@
import { import {
CheckSquareOutlined, CheckSquareOutlined,
CloudOutlined, CloudOutlined,
ClusterOutlined, ClusterOutlined,
CompressOutlined, CompressOutlined,
DatabaseOutlined, DatabaseOutlined,
InfoCircleOutlined, InfoCircleOutlined,
OpenAIOutlined, OpenAIOutlined,
QuestionOutlined, QuestionOutlined,
SunOutlined, SunOutlined,
SyncOutlined, SyncOutlined,
TableOutlined, TableOutlined,
ToolOutlined, ToolOutlined,
} from '@ant-design/icons' } from '@ant-design/icons'
import {values} from 'licia'
import {Navigate, type RouteObject} from 'react-router' import {Navigate, type RouteObject} from 'react-router'
import Conversation from './pages/ai/Conversation.tsx' import Conversation from './pages/ai/Conversation.tsx'
import Feedback from './pages/ai/feedback/Feedback.tsx'
import DataDetail from './pages/ai/knowledge/DataDetail.tsx' import DataDetail from './pages/ai/knowledge/DataDetail.tsx'
import DataImport from './pages/ai/knowledge/DataImport.tsx' import DataImport from './pages/ai/knowledge/DataImport.tsx'
import DataSegment from './pages/ai/knowledge/DataSegment.tsx' import DataSegment from './pages/ai/knowledge/DataSegment.tsx'
@@ -28,10 +30,8 @@ import Tool from './pages/overview/Tool.tsx'
import Version from './pages/overview/Version.tsx' import Version from './pages/overview/Version.tsx'
import Yarn from './pages/overview/Yarn.tsx' import Yarn from './pages/overview/Yarn.tsx'
import YarnCluster from './pages/overview/YarnCluster.tsx' import YarnCluster from './pages/overview/YarnCluster.tsx'
import {commonInfo} from './util/amis.tsx'
import Test from './pages/Test.tsx' import Test from './pages/Test.tsx'
import Feedback from './pages/ai/feedback/Feedback.tsx' import {commonInfo} from './util/amis.tsx'
import {values} from 'licia'
export const routes: RouteObject[] = [ export const routes: RouteObject[] = [
{ {
@@ -203,7 +203,7 @@ export const menus = {
}, },
{ {
path: '/ai/feedback', path: '/ai/feedback',
name: '智慧报', name: '智慧报',
icon: <CheckSquareOutlined/>, icon: <CheckSquareOutlined/>,
}, },
{ {

View File

@@ -281,6 +281,7 @@ export function crudCommonOptions() {
resizable: false, resizable: false,
syncLocation: false, syncLocation: false,
silentPolling: true, silentPolling: true,
columnsTogglable: false,
} }
} }

View File

@@ -1,5 +1,7 @@
server: server:
port: 0 port: 0
compression:
enabled: true
spring: spring:
application: application:
name: service-web name: service-web