feat(ai-web): 完成JPA存储适配
This commit is contained in:
@@ -1,11 +1,18 @@
|
|||||||
CREATE TABLE `service_ai_feedback`
|
CREATE TABLE `service_ai_feedback`
|
||||||
(
|
(
|
||||||
`id` bigint NOT NULL,
|
`id` bigint NOT NULL,
|
||||||
`source` longtext NOT NULL,
|
`created_time` datetime(6) DEFAULT NULL,
|
||||||
`conclusion` longtext,
|
`modified_time` datetime(6) DEFAULT NULL,
|
||||||
`analysis` longtext,
|
`analysis` longtext,
|
||||||
`pictures` longtext,
|
`conclusion` longtext,
|
||||||
`status` varchar(50) NOT NULL DEFAULT 'ANALYSIS_PROCESSING',
|
`source` longtext NOT NULL,
|
||||||
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`status` tinyint NOT NULL,
|
||||||
`modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
PRIMARY KEY (`id`)
|
||||||
|
) DEFAULT CHARSET = utf8mb4;
|
||||||
|
|
||||||
|
CREATE TABLE `service_ai_feedback_pictures`
|
||||||
|
(
|
||||||
|
`feedback_id` bigint NOT NULL,
|
||||||
|
`pictures_id` bigint NOT NULL,
|
||||||
|
PRIMARY KEY (`feedback_id`, `pictures_id`)
|
||||||
) DEFAULT CHARSET = utf8mb4;
|
) DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
CREATE TABLE `service_ai_file`
|
CREATE TABLE `service_ai_file`
|
||||||
(
|
(
|
||||||
`id` bigint NOT NULL,
|
`id` bigint NOT NULL,
|
||||||
`filename` varchar(500) DEFAULT NULL,
|
`created_time` datetime(6) DEFAULT NULL,
|
||||||
|
`modified_time` datetime(6) DEFAULT NULL,
|
||||||
|
`filename` varchar(255) DEFAULT NULL,
|
||||||
|
`md5` varchar(255) DEFAULT NULL,
|
||||||
|
`path` varchar(255) DEFAULT NULL,
|
||||||
`size` bigint DEFAULT NULL,
|
`size` bigint DEFAULT NULL,
|
||||||
`md5` varchar(100) DEFAULT NULL,
|
`type` varchar(255) DEFAULT NULL,
|
||||||
`path` varchar(500) DEFAULT NULL,
|
|
||||||
`type` varchar(50) DEFAULT NULL,
|
|
||||||
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) DEFAULT CHARSET = utf8mb4;
|
) DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
CREATE TABLE `service_ai_group`
|
CREATE TABLE `service_ai_group`
|
||||||
(
|
(
|
||||||
`id` bigint NOT NULL,
|
`id` bigint NOT NULL,
|
||||||
|
`created_time` datetime(6) DEFAULT NULL,
|
||||||
|
`modified_time` datetime(6) DEFAULT NULL,
|
||||||
|
`name` varchar(255) NOT NULL,
|
||||||
|
`status` tinyint NOT NULL,
|
||||||
`knowledge_id` bigint NOT NULL,
|
`knowledge_id` bigint NOT NULL,
|
||||||
`name` varchar(100) NOT NULL,
|
PRIMARY KEY (`id`)
|
||||||
`status` varchar(10) NOT NULL DEFAULT 'RUNNING',
|
|
||||||
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
`modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
||||||
) DEFAULT CHARSET=utf8mb4;
|
) DEFAULT CHARSET=utf8mb4;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
CREATE TABLE `service_ai_knowledge`
|
CREATE TABLE `service_ai_knowledge`
|
||||||
(
|
(
|
||||||
`id` bigint NOT NULL,
|
`id` bigint NOT NULL,
|
||||||
`vector_source_id` varchar(100) NOT NULL,
|
`created_time` datetime(6) DEFAULT NULL,
|
||||||
`name` varchar(100) NOT NULL,
|
`modified_time` datetime(6) DEFAULT NULL,
|
||||||
`description` longtext NOT NULL,
|
`description` longtext NOT NULL,
|
||||||
`strategy` varchar(10) NOT NULL,
|
`name` varchar(255) NOT NULL,
|
||||||
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`strategy` tinyint NOT NULL,
|
||||||
`modified_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`vector_source_id` bigint NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) DEFAULT CHARSET = utf8mb4;
|
) DEFAULT CHARSET = utf8mb4;
|
||||||
@@ -110,6 +110,11 @@
|
|||||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
<version>3.0.5</version>
|
<version>3.0.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.blinkfox</groupId>
|
||||||
|
<artifactId>fenix-spring-boot-starter</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- 日志相关 -->
|
<!-- 日志相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.core.configuration;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用雪花算法作为ID生成器
|
|
||||||
*
|
|
||||||
* @author lanyuanxiaoyao
|
|
||||||
* @date 2024-11-14
|
|
||||||
*/
|
|
||||||
public class SnowflakeId {
|
|
||||||
/**
|
|
||||||
* 起始的时间戳
|
|
||||||
*/
|
|
||||||
private final static long START_TIMESTAMP = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 序列号占用的位数
|
|
||||||
*/
|
|
||||||
private final static long SEQUENCE_BIT = 11;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 序列号最大值
|
|
||||||
*/
|
|
||||||
private final static long MAX_SEQUENCE_BIT = ~(-1 << SEQUENCE_BIT);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 时间戳值向左位移
|
|
||||||
*/
|
|
||||||
private final static long TIMESTAMP_OFFSET = SEQUENCE_BIT;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 序列号
|
|
||||||
*/
|
|
||||||
private static long sequence = 0;
|
|
||||||
/**
|
|
||||||
* 上一次时间戳
|
|
||||||
*/
|
|
||||||
private static long lastTimestamp = -1;
|
|
||||||
|
|
||||||
public static synchronized long next() {
|
|
||||||
long currentTimestamp = nowTimestamp();
|
|
||||||
if (currentTimestamp < lastTimestamp) {
|
|
||||||
throw new RuntimeException("Clock have moved backwards.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentTimestamp == lastTimestamp) {
|
|
||||||
// 相同毫秒内, 序列号自增
|
|
||||||
sequence = (sequence + 1) & MAX_SEQUENCE_BIT;
|
|
||||||
// 同一毫秒的序列数已经达到最大
|
|
||||||
if (sequence == 0) {
|
|
||||||
currentTimestamp = nextTimestamp();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 不同毫秒内, 序列号置为0
|
|
||||||
sequence = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTimestamp = currentTimestamp;
|
|
||||||
return (currentTimestamp - START_TIMESTAMP) << TIMESTAMP_OFFSET | sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long nextTimestamp() {
|
|
||||||
long milli = nowTimestamp();
|
|
||||||
while (milli <= lastTimestamp) {
|
|
||||||
milli = nowTimestamp();
|
|
||||||
}
|
|
||||||
return milli;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static long nowTimestamp() {
|
|
||||||
return Instant.now().toEpochMilli();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -53,7 +53,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.blinkfox</groupId>
|
<groupId>com.blinkfox</groupId>
|
||||||
<artifactId>fenix-spring-boot-starter</artifactId>
|
<artifactId>fenix-spring-boot-starter</artifactId>
|
||||||
<version>3.0.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.base.controller;
|
package com.lanyuanxiaoyao.service.ai.web.base.controller;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisCrudResponse;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.controller.query.Query;
|
import com.lanyuanxiaoyao.service.ai.web.base.controller.query.Query;
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lanyuanxiaoyao
|
* @author lanyuanxiaoyao
|
||||||
* @date 2024-11-28
|
* @date 2024-11-28
|
||||||
*/
|
*/
|
||||||
public interface ListController<LIST_ITEM> {
|
public interface ListController {
|
||||||
String LIST = "/list";
|
String LIST = "/list";
|
||||||
|
|
||||||
AmisResponse<ImmutableList<LIST_ITEM>> list() throws Exception;
|
AmisCrudResponse list() throws Exception;
|
||||||
|
|
||||||
AmisResponse<ImmutableList<LIST_ITEM>> list(Query query) throws Exception;
|
AmisCrudResponse list(Query query) throws Exception;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ package com.lanyuanxiaoyao.service.ai.web.base.controller;
|
|||||||
* @author lanyuanxiaoyao
|
* @author lanyuanxiaoyao
|
||||||
* @date 2024-11-28
|
* @date 2024-11-28
|
||||||
*/
|
*/
|
||||||
public interface SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> extends SaveController<SAVE_ITEM>, ListController<LIST_ITEM>, DetailController<DETAIL_ITEM>, RemoveController {
|
public interface SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> extends SaveController<SAVE_ITEM>, ListController, DetailController<DETAIL_ITEM>, RemoveController {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.base.controller;
|
package com.lanyuanxiaoyao.service.ai.web.base.controller;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisCrudResponse;
|
||||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.controller.query.Query;
|
import com.lanyuanxiaoyao.service.ai.web.base.controller.query.Query;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.service.SimpleServiceSupport;
|
import com.lanyuanxiaoyao.service.ai.web.base.service.SimpleServiceSupport;
|
||||||
|
import java.util.List;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.eclipse.collections.api.factory.Lists;
|
import org.springframework.data.domain.Page;
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -34,43 +35,52 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
|
|||||||
|
|
||||||
@GetMapping(LIST)
|
@GetMapping(LIST)
|
||||||
@Override
|
@Override
|
||||||
public AmisResponse<ImmutableList<LIST_ITEM>> list() throws Exception {
|
public AmisCrudResponse list() throws Exception {
|
||||||
ListItemMapper<ENTITY, LIST_ITEM> mapper = listItemMapper();
|
ListItemMapper<ENTITY, LIST_ITEM> mapper = listItemMapper();
|
||||||
return AmisResponse.responseSuccess(service.list().collect(entity -> {
|
return AmisCrudResponse.responseCrudData(
|
||||||
|
service.list()
|
||||||
|
.collect(entity -> {
|
||||||
try {
|
try {
|
||||||
return mapper.from(entity);
|
return mapper.from(entity);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(LIST)
|
@PostMapping(LIST)
|
||||||
@Override
|
@Override
|
||||||
public AmisResponse<ImmutableList<LIST_ITEM>> list(@RequestBody Query query) throws Exception {
|
public AmisCrudResponse list(@RequestBody Query query) throws Exception {
|
||||||
if (ObjectUtil.isNull(query)) {
|
if (ObjectUtil.isNull(query)) {
|
||||||
return AmisResponse.responseSuccess(Lists.immutable.empty());
|
return AmisCrudResponse.responseCrudData(List.of(), 0);
|
||||||
}
|
}
|
||||||
ListItemMapper<ENTITY, LIST_ITEM> mapper = listItemMapper();
|
ListItemMapper<ENTITY, LIST_ITEM> mapper = listItemMapper();
|
||||||
return AmisResponse.responseSuccess(service.list(query).collect(entity -> {
|
Page<ENTITY> result = service.list(query);
|
||||||
|
return AmisCrudResponse.responseCrudData(
|
||||||
|
result.get()
|
||||||
|
.map(entity -> {
|
||||||
try {
|
try {
|
||||||
return mapper.from(entity);
|
return mapper.from(entity);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}));
|
})
|
||||||
|
.toList(),
|
||||||
|
result.getTotalElements()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(DETAIL)
|
@GetMapping(DETAIL)
|
||||||
@Override
|
@Override
|
||||||
public AmisResponse<DETAIL_ITEM> detail(@PathVariable Long id) throws Exception {
|
public AmisResponse<DETAIL_ITEM> detail(@PathVariable("id") Long id) throws Exception {
|
||||||
DetailItemMapper<ENTITY, DETAIL_ITEM> mapper = detailItemMapper();
|
DetailItemMapper<ENTITY, DETAIL_ITEM> mapper = detailItemMapper();
|
||||||
return AmisResponse.responseSuccess(mapper.from(service.detailOrThrow(id)));
|
return AmisResponse.responseSuccess(mapper.from(service.detailOrThrow(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(REMOVE)
|
@GetMapping(REMOVE)
|
||||||
@Override
|
@Override
|
||||||
public AmisResponse<Object> remove(@PathVariable Long id) throws Exception {
|
public AmisResponse<Object> remove(@PathVariable("id") Long id) throws Exception {
|
||||||
service.remove(id);
|
service.remove(id);
|
||||||
return AmisResponse.responseSuccess();
|
return AmisResponse.responseSuccess();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
import org.eclipse.collections.api.list.ImmutableList;
|
||||||
import org.eclipse.collections.api.set.ImmutableSet;
|
import org.eclipse.collections.api.set.ImmutableSet;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lanyuanxiaoyao
|
* @author lanyuanxiaoyao
|
||||||
@@ -19,7 +20,7 @@ public interface SimpleService<ENTITY extends SimpleEntity> {
|
|||||||
|
|
||||||
ImmutableList<ENTITY> list(ImmutableSet<Long> ids) throws Exception;
|
ImmutableList<ENTITY> list(ImmutableSet<Long> ids) throws Exception;
|
||||||
|
|
||||||
ImmutableList<ENTITY> list(Query query) throws Exception;
|
Page<ENTITY> list(Query query) throws Exception;
|
||||||
|
|
||||||
Optional<ENTITY> detailOptional(Long id) throws Exception;
|
Optional<ENTITY> detailOptional(Long id) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ import org.eclipse.collections.api.factory.Lists;
|
|||||||
import org.eclipse.collections.api.list.ImmutableList;
|
import org.eclipse.collections.api.list.ImmutableList;
|
||||||
import org.eclipse.collections.api.list.MutableList;
|
import org.eclipse.collections.api.list.MutableList;
|
||||||
import org.eclipse.collections.api.set.ImmutableSet;
|
import org.eclipse.collections.api.set.ImmutableSet;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +32,8 @@ import org.springframework.data.domain.Sort;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implements SimpleService<ENTITY> {
|
public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implements SimpleService<ENTITY> {
|
||||||
|
private static final Integer DEFAULT_PAGE_INDEX = 1;
|
||||||
|
private static final Integer DEFAULT_PAGE_SIZE = 10;
|
||||||
protected final SimpleRepository<ENTITY, Long> repository;
|
protected final SimpleRepository<ENTITY, Long> repository;
|
||||||
|
|
||||||
public SimpleServiceSupport(SimpleRepository<ENTITY, Long> repository) {
|
public SimpleServiceSupport(SimpleRepository<ENTITY, Long> repository) {
|
||||||
@@ -38,7 +42,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
|
|
||||||
@Transactional(rollbackOn = Throwable.class)
|
@Transactional(rollbackOn = Throwable.class)
|
||||||
@Override
|
@Override
|
||||||
public Long save(ENTITY entity) throws Exception {
|
public Long save(ENTITY entity) {
|
||||||
if (ObjectUtil.isNotNull(entity.getId())) {
|
if (ObjectUtil.isNotNull(entity.getId())) {
|
||||||
Long id = entity.getId();
|
Long id = entity.getId();
|
||||||
ENTITY targetEntity = repository.findById(entity.getId()).orElseThrow(() -> new IdNotFoundException(id));
|
ENTITY targetEntity = repository.findById(entity.getId()).orElseThrow(() -> new IdNotFoundException(id));
|
||||||
@@ -59,7 +63,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long count() throws Exception {
|
public Long count() {
|
||||||
return repository.count(
|
return repository.count(
|
||||||
(root, query, builder) ->
|
(root, query, builder) ->
|
||||||
builder.and(
|
builder.and(
|
||||||
@@ -71,7 +75,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableList<ENTITY> list() throws Exception {
|
public ImmutableList<ENTITY> list() {
|
||||||
return Lists.immutable.ofAll(repository.findAll(
|
return Lists.immutable.ofAll(repository.findAll(
|
||||||
(root, query, builder) ->
|
(root, query, builder) ->
|
||||||
builder.and(
|
builder.and(
|
||||||
@@ -83,7 +87,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableList<ENTITY> list(ImmutableSet<Long> ids) throws Exception {
|
public ImmutableList<ENTITY> list(ImmutableSet<Long> ids) {
|
||||||
return Lists.immutable.ofAll(repository.findAll(
|
return Lists.immutable.ofAll(repository.findAll(
|
||||||
(root, query, builder) -> {
|
(root, query, builder) -> {
|
||||||
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicate(root, query, builder));
|
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicate(root, query, builder));
|
||||||
@@ -179,15 +183,23 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableList<ENTITY> list(Query listQuery) throws Exception {
|
public Page<ENTITY> list(Query listQuery) {
|
||||||
return Lists.immutable.ofAll(repository.findAll(
|
PageRequest pageRequest = PageRequest.of(DEFAULT_PAGE_INDEX - 1, DEFAULT_PAGE_SIZE, Sort.by(SimpleEntity_.CREATED_TIME).descending());
|
||||||
|
if (ObjectUtil.isNotNull(listQuery.getPage())) {
|
||||||
|
pageRequest = PageRequest.of(
|
||||||
|
ObjectUtil.defaultIfNull(listQuery.getPage().getIndex(), DEFAULT_PAGE_INDEX) - 1,
|
||||||
|
ObjectUtil.defaultIfNull(listQuery.getPage().getSize(), DEFAULT_PAGE_SIZE),
|
||||||
|
Sort.by(SimpleEntity_.CREATED_TIME).descending()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return repository.findAll(
|
||||||
(root, query, builder) -> {
|
(root, query, builder) -> {
|
||||||
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicate(root, query, builder));
|
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicate(root, query, builder));
|
||||||
predicates.addAllIterable(queryPredicates(listQuery.getQuery(), root, query, builder));
|
predicates.addAllIterable(queryPredicates(listQuery.getQuery(), root, query, builder));
|
||||||
return builder.and(predicates.reject(ObjectUtil::isNull).toArray(new Predicate[predicates.size()]));
|
return builder.and(predicates.reject(ObjectUtil::isNull).toArray(new Predicate[predicates.size()]));
|
||||||
},
|
},
|
||||||
Sort.by(SimpleEntity_.CREATED_TIME).descending()
|
pageRequest
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -221,7 +233,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
|
|||||||
|
|
||||||
@Transactional(rollbackOn = Throwable.class)
|
@Transactional(rollbackOn = Throwable.class)
|
||||||
@Override
|
@Override
|
||||||
public void remove(Long id) throws Exception {
|
public void remove(Long id) {
|
||||||
if (ObjectUtil.isNotNull(id)) {
|
if (ObjectUtil.isNotNull(id)) {
|
||||||
repository.deleteById(id);
|
repository.deleteById(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.lanyuanxiaoyao.service.ai.web.base.controller.SimpleControllerSupport
|
|||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.IdOnlyEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.IdOnlyEntity;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleItem;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleItem;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.Feedback;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Feedback;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.service.DataFileService;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.service.feedback.FeedbackService;
|
import com.lanyuanxiaoyao.service.ai.web.service.feedback.FeedbackService;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
@@ -22,12 +23,14 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("feedback")
|
@RequestMapping("feedback")
|
||||||
public class FeedbackController extends SimpleControllerSupport<Feedback, FeedbackController.SaveItem, FeedbackController.ListItem, FeedbackController.DetailItem> {
|
public class FeedbackController extends SimpleControllerSupport<Feedback, FeedbackController.SaveItem, FeedbackController.ListItem, FeedbackController.ListItem> {
|
||||||
private final FeedbackService feedbackService;
|
private final FeedbackService feedbackService;
|
||||||
|
private final DataFileService dataFileService;
|
||||||
|
|
||||||
public FeedbackController(FeedbackService feedbackService) {
|
public FeedbackController(FeedbackService feedbackService, DataFileService dataFileService) {
|
||||||
super(feedbackService);
|
super(feedbackService);
|
||||||
this.feedbackService = feedbackService;
|
this.feedbackService = feedbackService;
|
||||||
|
this.dataFileService = dataFileService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("reanalysis/{id}")
|
@GetMapping("reanalysis/{id}")
|
||||||
@@ -42,7 +45,12 @@ public class FeedbackController extends SimpleControllerSupport<Feedback, Feedba
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SaveItemMapper<Feedback, SaveItem> saveItemMapper() {
|
protected SaveItemMapper<Feedback, SaveItem> saveItemMapper() {
|
||||||
return null;
|
return item -> {
|
||||||
|
Feedback feedback = new Feedback();
|
||||||
|
feedback.setSource(item.getSource());
|
||||||
|
feedback.setPictures(dataFileService.downloadFile(item.getPictures()).toSet());
|
||||||
|
return feedback;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -51,8 +59,9 @@ public class FeedbackController extends SimpleControllerSupport<Feedback, Feedba
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DetailItemMapper<Feedback, DetailItem> detailItemMapper() {
|
protected DetailItemMapper<Feedback, ListItem> detailItemMapper() {
|
||||||
return Mappers.getMapper(DetailItem.Mapper.class);
|
ListItemMapper<Feedback, ListItem> mapper = listItemMapper();
|
||||||
|
return mapper::from;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -88,20 +97,4 @@ public class FeedbackController extends SimpleControllerSupport<Feedback, Feedba
|
|||||||
ListItem from(Feedback feedback);
|
ListItem from(Feedback feedback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
|
||||||
public static final class DetailItem extends ListItem {
|
|
||||||
@org.mapstruct.Mapper(
|
|
||||||
imports = {
|
|
||||||
IdOnlyEntity.class,
|
|
||||||
Sets.class
|
|
||||||
}
|
|
||||||
)
|
|
||||||
public interface Mapper extends DetailItemMapper<Feedback, DetailItem> {
|
|
||||||
@Mapping(target = "pictures", expression = "java(Sets.immutable.ofAll(feedback.getPictures()).collect(IdOnlyEntity::getId))")
|
|
||||||
@Override
|
|
||||||
DetailItem from(Feedback feedback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.controller.knowledge;
|
package com.lanyuanxiaoyao.service.ai.web.controller.knowledge;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.core.entity.amis.AmisResponse;
|
import com.lanyuanxiaoyao.service.ai.web.base.controller.SimpleControllerSupport;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleItem;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.entity.Group;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.service.knowledge.GroupService;
|
import com.lanyuanxiaoyao.service.ai.web.service.knowledge.GroupService;
|
||||||
import java.util.concurrent.ExecutionException;
|
import com.lanyuanxiaoyao.service.ai.web.service.knowledge.KnowledgeBaseService;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.mapstruct.factory.Mappers;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,21 +19,49 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("knowledge/group")
|
@RequestMapping("knowledge/group")
|
||||||
public class GroupController {
|
public class GroupController extends SimpleControllerSupport<Group, GroupController.SaveItem, GroupController.ListItem, GroupController.ListItem> {
|
||||||
private final GroupService groupService;
|
private final KnowledgeBaseService knowledgeBaseService;
|
||||||
|
|
||||||
public GroupController(GroupService groupService) {
|
public GroupController(GroupService groupService, KnowledgeBaseService knowledgeBaseService) {
|
||||||
this.groupService = groupService;
|
super(groupService);
|
||||||
|
this.knowledgeBaseService = knowledgeBaseService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("list")
|
@Override
|
||||||
public AmisResponse<?> list(@RequestParam("knowledge_id") Long knowledgeId) {
|
protected SaveItemMapper<Group, SaveItem> saveItemMapper() {
|
||||||
return AmisResponse.responseCrudData(groupService.list(knowledgeId));
|
return item -> {
|
||||||
|
Group group = new Group();
|
||||||
|
group.setName(item.getName());
|
||||||
|
group.setKnowledge(knowledgeBaseService.detailOrThrow(item.getKnowledgeId()));
|
||||||
|
return group;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("delete")
|
@Override
|
||||||
public AmisResponse<?> delete(@RequestParam("id") Long id) throws ExecutionException, InterruptedException {
|
protected ListItemMapper<Group, ListItem> listItemMapper() {
|
||||||
groupService.remove(id);
|
return Mappers.getMapper(ListItem.Mapper.class);
|
||||||
return AmisResponse.responseSuccess();
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DetailItemMapper<Group, ListItem> detailItemMapper() {
|
||||||
|
ListItemMapper<Group, ListItem> mapper = listItemMapper();
|
||||||
|
return mapper::from;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static final class SaveItem {
|
||||||
|
private String name;
|
||||||
|
private Long knowledgeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public static final class ListItem extends SimpleItem {
|
||||||
|
private String name;
|
||||||
|
private Group.Status status;
|
||||||
|
|
||||||
|
@org.mapstruct.Mapper
|
||||||
|
public interface Mapper extends ListItemMapper<Group, ListItem> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("knowledge")
|
@RequestMapping("knowledge")
|
||||||
public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge, KnowledgeBaseController.SaveItem, KnowledgeBaseController.ListItem, KnowledgeBaseController.DetailItem> {
|
public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge, KnowledgeBaseController.SaveItem, KnowledgeBaseController.ListItem, KnowledgeBaseController.ListItem> {
|
||||||
private final KnowledgeBaseService knowledgeBaseService;
|
private final KnowledgeBaseService knowledgeBaseService;
|
||||||
private final EmbeddingService embeddingService;
|
private final EmbeddingService embeddingService;
|
||||||
|
|
||||||
@@ -44,20 +44,6 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
this.embeddingService = embeddingService;
|
this.embeddingService = embeddingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("update_description")
|
|
||||||
public void updateDescription(
|
|
||||||
@RequestParam("id") Long id,
|
|
||||||
@RequestParam("description") String description
|
|
||||||
) throws Exception {
|
|
||||||
knowledgeBaseService.updateDescription(id, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("name/{id}")
|
|
||||||
public AmisMapResponse name(@PathVariable("id") Long id) {
|
|
||||||
return AmisResponse.responseMapData()
|
|
||||||
.setData("name", knowledgeBaseService.getName(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SaveItemMapper<Knowledge, SaveItem> saveItemMapper() {
|
protected SaveItemMapper<Knowledge, SaveItem> saveItemMapper() {
|
||||||
return Mappers.getMapper(SaveItem.Mapper.class);
|
return Mappers.getMapper(SaveItem.Mapper.class);
|
||||||
@@ -66,25 +52,34 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
@Override
|
@Override
|
||||||
protected ListItemMapper<Knowledge, ListItem> listItemMapper() {
|
protected ListItemMapper<Knowledge, ListItem> listItemMapper() {
|
||||||
ListItem.Mapper mapper = Mappers.getMapper(ListItem.Mapper.class);
|
ListItem.Mapper mapper = Mappers.getMapper(ListItem.Mapper.class);
|
||||||
return knowledge -> mapper.from(knowledge, knowledgeBaseService.getCollectionInfoById(knowledge.getVectorSourceId()));
|
return knowledge -> mapper.from(knowledge, knowledgeBaseService.collectionInfo(knowledge.getVectorSourceId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DetailItemMapper<Knowledge, DetailItem> detailItemMapper() {
|
protected DetailItemMapper<Knowledge, ListItem> detailItemMapper() {
|
||||||
DetailItem.Mapper mapper = Mappers.getMapper(DetailItem.Mapper.class);
|
ListItem.Mapper mapper = Mappers.getMapper(ListItem.Mapper.class);
|
||||||
return knowledge -> mapper.from(knowledge, knowledgeBaseService.getCollectionInfoById(knowledge.getVectorSourceId()));
|
return knowledge -> mapper.from(knowledge, knowledgeBaseService.collectionInfo(knowledge.getVectorSourceId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("{id}/name")
|
||||||
|
public AmisMapResponse name(@PathVariable("id") Long id) {
|
||||||
|
return AmisResponse.responseMapData()
|
||||||
|
.setData("name", knowledgeBaseService.getName(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("update_description")
|
||||||
|
public void updateDescription(
|
||||||
|
@RequestParam("id") Long id,
|
||||||
|
@RequestParam("description") String description
|
||||||
|
) throws Exception {
|
||||||
|
knowledgeBaseService.updateDescription(id, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("preview_text")
|
@PostMapping("preview_text")
|
||||||
public AmisResponse<?> previewText(
|
public AmisResponse<?> previewText(@RequestBody SubmitItem item) {
|
||||||
@RequestParam(value = "mode", defaultValue = "NORMAL") String mode,
|
if (StrUtil.equals("text", item.getType())) {
|
||||||
@RequestParam(value = "type", defaultValue = "text") String type,
|
|
||||||
@RequestParam(value = "content", required = false) String content,
|
|
||||||
@RequestParam(value = "files", required = false) String files
|
|
||||||
) {
|
|
||||||
if (StrUtil.equals("text", type)) {
|
|
||||||
return AmisResponse.responseCrudData(
|
return AmisResponse.responseCrudData(
|
||||||
embeddingService.preview(mode, content)
|
embeddingService.preview(item.getMode(), item.getContent())
|
||||||
.collect(doc -> {
|
.collect(doc -> {
|
||||||
SegmentVO vo = new SegmentVO();
|
SegmentVO vo = new SegmentVO();
|
||||||
vo.setId(doc.getId());
|
vo.setId(doc.getId());
|
||||||
@@ -92,9 +87,9 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
return vo;
|
return vo;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else if (StrUtil.equals("file", type)) {
|
} else if (StrUtil.equals("file", item.getType())) {
|
||||||
return AmisResponse.responseCrudData(
|
return AmisResponse.responseCrudData(
|
||||||
embeddingService.preview(mode, Lists.immutable.of(files.split(",")))
|
embeddingService.preview(item.getMode(), item.getFiles())
|
||||||
.collect(doc -> {
|
.collect(doc -> {
|
||||||
SegmentVO vo = new SegmentVO();
|
SegmentVO vo = new SegmentVO();
|
||||||
vo.setId(doc.getId());
|
vo.setId(doc.getId());
|
||||||
@@ -103,45 +98,29 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported type: " + type);
|
throw new IllegalArgumentException("Unsupported type: " + item.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("submit_text")
|
@PostMapping("submit_text")
|
||||||
public void submitText(
|
public void submitText(@RequestBody SubmitItem item) {
|
||||||
@RequestParam("id") Long id,
|
if (StrUtil.equals("text", item.getMode())) {
|
||||||
@RequestParam(value = "mode", defaultValue = "NORMAL") String mode,
|
embeddingService.submit(item.getId(), item.getMode(), item.getContent());
|
||||||
@RequestParam(value = "type", defaultValue = "text") String type,
|
} else if (StrUtil.equals("file", item.getType())) {
|
||||||
@RequestParam(value = "content", required = false) String content,
|
embeddingService.submit(item.getId(), item.getMode(), item.getFiles());
|
||||||
@RequestParam(value = "files", required = false) String files
|
|
||||||
) {
|
|
||||||
if (StrUtil.equals("text", type)) {
|
|
||||||
embeddingService.submit(id, mode, content);
|
|
||||||
} else if (StrUtil.equals("file", type)) {
|
|
||||||
embeddingService.submit(id, mode, Lists.immutable.of(files.split(",")));
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported type: " + type);
|
throw new IllegalArgumentException("Unsupported type: " + item.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("submit_text_directly")
|
@PostMapping("submit_text_directly")
|
||||||
public void submitDirectly(
|
public void submitDirectly(@RequestBody SubmitDirectlyItem item) {
|
||||||
@RequestParam("id") Long id,
|
embeddingService.submitDirectly(item.getId(), item.getName(), Lists.immutable.ofAll(StrUtil.split(item.getContent(), item.getSplitKey())));
|
||||||
@RequestParam(value = "name", required = false) String name,
|
|
||||||
@RequestParam(value = "split_key", defaultValue = "\n\n") String splitKey,
|
|
||||||
@RequestBody String content
|
|
||||||
) {
|
|
||||||
embeddingService.submitDirectly(id, name, Lists.immutable.of(content.split(splitKey)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("query")
|
@PostMapping("query")
|
||||||
public ImmutableList<String> query(
|
public ImmutableList<String> query(@RequestBody QueryItem item) throws ExecutionException, InterruptedException, IOException {
|
||||||
@RequestParam("id") Long id,
|
return knowledgeBaseService.query(item.getId(), item.getText(), item.getLimit(), item.getThreshold());
|
||||||
@RequestParam(value = "limit", defaultValue = "5") Integer limit,
|
|
||||||
@RequestParam(value = "threshold", defaultValue = "0.6") Double threshold,
|
|
||||||
@RequestBody String text
|
|
||||||
) throws ExecutionException, InterruptedException, IOException {
|
|
||||||
return knowledgeBaseService.query(id, text, limit, threshold);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -157,7 +136,7 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public static class ListItem extends SimpleItem {
|
public static final class ListItem extends SimpleItem {
|
||||||
private Long vectorSourceId;
|
private Long vectorSourceId;
|
||||||
private String name;
|
private String name;
|
||||||
private String description;
|
private String description;
|
||||||
@@ -179,16 +158,27 @@ public class KnowledgeBaseController extends SimpleControllerSupport<Knowledge,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
public static final class SubmitItem {
|
||||||
public static final class DetailItem extends ListItem {
|
private Long id;
|
||||||
@org.mapstruct.Mapper
|
private String mode;
|
||||||
public interface Mapper extends DetailItemMapper<Knowledge, ListItem> {
|
private String type;
|
||||||
@Mapping(source = "info.config.params.vectorsConfig.params.distance", target = "strategy")
|
private String content;
|
||||||
@Mapping(source = "info.config.params.vectorsConfig.params.size", target = "size")
|
private ImmutableList<Long> files;
|
||||||
@Mapping(source = "info.pointsCount", target = "points")
|
}
|
||||||
@Mapping(source = "info.segmentsCount", target = "segments")
|
|
||||||
@Mapping(source = "info.status", target = "status")
|
@Data
|
||||||
DetailItem from(Knowledge knowledge, Collections.CollectionInfo info);
|
public static final class SubmitDirectlyItem {
|
||||||
}
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private String splitKey = "\n\n";
|
||||||
|
private String content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static final class QueryItem {
|
||||||
|
private Long id;
|
||||||
|
private Integer limit = 5;
|
||||||
|
private Double threshold = 0.6;
|
||||||
|
private String text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.entity;
|
package com.lanyuanxiaoyao.service.ai.web.entity;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
||||||
|
import com.lanyuanxiaoyao.service.common.Constants;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -20,7 +21,7 @@ import org.hibernate.annotations.DynamicUpdate;
|
|||||||
@ToString
|
@ToString
|
||||||
@Entity
|
@Entity
|
||||||
@DynamicUpdate
|
@DynamicUpdate
|
||||||
@Table(name = "service_ai_file")
|
@Table(catalog = Constants.DATABASE_NAME, name = "service_ai_file")
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class DataFile extends SimpleEntity {
|
public class DataFile extends SimpleEntity {
|
||||||
private String filename;
|
private String filename;
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.entity;
|
package com.lanyuanxiaoyao.service.ai.web.entity;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
||||||
|
import com.lanyuanxiaoyao.service.common.Constants;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.ConstraintMode;
|
import jakarta.persistence.ConstraintMode;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.EntityListeners;
|
import jakarta.persistence.EntityListeners;
|
||||||
import jakarta.persistence.FetchType;
|
import jakarta.persistence.FetchType;
|
||||||
import jakarta.persistence.ForeignKey;
|
import jakarta.persistence.ForeignKey;
|
||||||
import jakarta.persistence.JoinTable;
|
import jakarta.persistence.JoinTable;
|
||||||
|
import jakarta.persistence.NamedAttributeNode;
|
||||||
|
import jakarta.persistence.NamedEntityGraph;
|
||||||
import jakarta.persistence.OneToMany;
|
import jakarta.persistence.OneToMany;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -22,15 +26,22 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
@Entity
|
@Entity
|
||||||
@DynamicUpdate
|
@DynamicUpdate
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
@EntityListeners(AuditingEntityListener.class)
|
||||||
@Table(name = "service_ai_feedback")
|
@Table(catalog = Constants.DATABASE_NAME, name = "service_ai_feedback")
|
||||||
|
@NamedEntityGraph(name = "feedback.detail", attributeNodes = {
|
||||||
|
@NamedAttributeNode("pictures")
|
||||||
|
})
|
||||||
public class Feedback extends SimpleEntity {
|
public class Feedback extends SimpleEntity {
|
||||||
|
@Column(nullable = false, columnDefinition = "longtext")
|
||||||
private String source;
|
private String source;
|
||||||
@OneToMany(fetch = FetchType.LAZY)
|
@OneToMany(fetch = FetchType.EAGER)
|
||||||
@JoinTable(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
@JoinTable(catalog = Constants.DATABASE_NAME, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
private Set<DataFile> pictures;
|
private Set<DataFile> pictures;
|
||||||
|
@Column(columnDefinition = "longtext")
|
||||||
private String analysis;
|
private String analysis;
|
||||||
|
@Column(columnDefinition = "longtext")
|
||||||
private String conclusion;
|
private String conclusion;
|
||||||
|
@Column(nullable = false)
|
||||||
private Status status = Status.ANALYSIS_PROCESSING;
|
private Status status = Status.ANALYSIS_PROCESSING;
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.entity;
|
package com.lanyuanxiaoyao.service.ai.web.entity;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
||||||
|
import com.lanyuanxiaoyao.service.common.Constants;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.ConstraintMode;
|
import jakarta.persistence.ConstraintMode;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.EntityListeners;
|
import jakarta.persistence.EntityListeners;
|
||||||
@@ -25,13 +27,20 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
@Entity
|
@Entity
|
||||||
@DynamicUpdate
|
@DynamicUpdate
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
@EntityListeners(AuditingEntityListener.class)
|
||||||
@Table(name = "service_ai_group")
|
@Table(catalog = Constants.DATABASE_NAME, name = "service_ai_group")
|
||||||
public class Group extends SimpleEntity {
|
public class Group extends SimpleEntity {
|
||||||
|
@Column(nullable = false)
|
||||||
private String name;
|
private String name;
|
||||||
private String status;
|
@Column(nullable = false)
|
||||||
|
private Status status = Status.RUNNING;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
private Knowledge knowledge;
|
private Knowledge knowledge;
|
||||||
|
|
||||||
|
public enum Status {
|
||||||
|
RUNNING,
|
||||||
|
FINISHED,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.entity;
|
package com.lanyuanxiaoyao.service.ai.web.entity;
|
||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
import com.lanyuanxiaoyao.service.ai.web.base.entity.SimpleEntity;
|
||||||
|
import com.lanyuanxiaoyao.service.common.Constants;
|
||||||
import jakarta.persistence.CascadeType;
|
import jakarta.persistence.CascadeType;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.Entity;
|
||||||
import jakarta.persistence.EntityListeners;
|
import jakarta.persistence.EntityListeners;
|
||||||
import jakarta.persistence.FetchType;
|
import jakarta.persistence.FetchType;
|
||||||
@@ -24,14 +26,23 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
|||||||
@Entity
|
@Entity
|
||||||
@DynamicUpdate
|
@DynamicUpdate
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
@EntityListeners(AuditingEntityListener.class)
|
||||||
@Table(name = "service_ai_knowledge")
|
@Table(catalog = Constants.DATABASE_NAME, name = "service_ai_knowledge")
|
||||||
public class Knowledge extends SimpleEntity {
|
public class Knowledge extends SimpleEntity {
|
||||||
|
@Column(nullable = false)
|
||||||
private Long vectorSourceId;
|
private Long vectorSourceId;
|
||||||
|
@Column(nullable = false)
|
||||||
private String name;
|
private String name;
|
||||||
|
@Column(nullable = false, columnDefinition = "longtext")
|
||||||
private String description;
|
private String description;
|
||||||
private String strategy;
|
@Column(nullable = false)
|
||||||
|
private Strategy strategy = Strategy.Cosine;
|
||||||
|
|
||||||
@OneToMany(fetch = FetchType.LAZY, mappedBy = "knowledge", cascade = CascadeType.ALL)
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "knowledge", cascade = CascadeType.ALL)
|
||||||
@ToString.Exclude
|
@ToString.Exclude
|
||||||
private Set<Group> groups;
|
private Set<Group> groups;
|
||||||
|
|
||||||
|
public enum Strategy {
|
||||||
|
Cosine,
|
||||||
|
Euclid,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,25 @@ package com.lanyuanxiaoyao.service.ai.web.repository;
|
|||||||
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.repository.SimpleRepository;
|
import com.lanyuanxiaoyao.service.ai.web.base.repository.SimpleRepository;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.Feedback;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Feedback;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.data.jpa.repository.EntityGraph;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@SuppressWarnings("NullableProblems")
|
||||||
@Repository
|
@Repository
|
||||||
public interface FeedbackRepository extends SimpleRepository<Feedback, Long> {
|
public interface FeedbackRepository extends SimpleRepository<Feedback, Long> {
|
||||||
|
@EntityGraph(value = "feedback.detail", type = EntityGraph.EntityGraphType.FETCH)
|
||||||
|
@Override
|
||||||
|
List<Feedback> findAll(Specification<Feedback> specification);
|
||||||
|
|
||||||
|
@EntityGraph(value = "feedback.detail", type = EntityGraph.EntityGraphType.FETCH)
|
||||||
|
@Override
|
||||||
|
List<Feedback> findAll(Specification<Feedback> specification, Sort sort);
|
||||||
|
|
||||||
|
@EntityGraph(value = "feedback.detail", type = EntityGraph.EntityGraphType.FETCH)
|
||||||
|
@Override
|
||||||
|
Optional<Feedback> findOne(Specification<Feedback> specification);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Pair;
|
|||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.DataFile;
|
import com.lanyuanxiaoyao.service.ai.web.entity.DataFile;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.entity.Group;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.Knowledge;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Knowledge;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.context.EmbeddingContext;
|
import com.lanyuanxiaoyao.service.ai.web.entity.context.EmbeddingContext;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.service.knowledge.GroupService;
|
import com.lanyuanxiaoyao.service.ai.web.service.knowledge.GroupService;
|
||||||
@@ -54,16 +55,19 @@ public class EmbeddingService {
|
|||||||
return Lists.immutable.ofAll(context.getDocuments());
|
return Lists.immutable.ofAll(context.getDocuments());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableList<Document> preview(String mode, ImmutableList<String> ids) {
|
public ImmutableList<Document> preview(String mode, ImmutableList<Long> ids) {
|
||||||
DataFile dataFile = dataFileService.downloadFile(Long.parseLong(ids.get(0)));
|
DataFile dataFile = dataFileService.downloadFile(ids.get(0));
|
||||||
String content = FileUtil.readString(dataFile.getPath(), StandardCharsets.UTF_8);
|
String content = FileUtil.readString(dataFile.getPath(), StandardCharsets.UTF_8);
|
||||||
return preview(mode, content);
|
return preview(mode, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submit(Long id, String mode, String content) {
|
public void submit(Long id, String mode, String content) {
|
||||||
executors.submit(() -> {
|
executors.submit(() -> {
|
||||||
Knowledge knowledge = knowledgeBaseService.get(id);
|
Knowledge knowledge = knowledgeBaseService.detailOrThrow(id);
|
||||||
Long groupId = groupService.add(knowledge.getId(), StrUtil.format("文本-{}", IdUtil.nanoId(10)));
|
Group group = new Group();
|
||||||
|
group.setName(StrUtil.format("文本-{}", IdUtil.nanoId(10)));
|
||||||
|
group.setKnowledge(knowledge);
|
||||||
|
Long groupId = groupService.save(group);
|
||||||
EmbeddingContext context = EmbeddingContext.builder()
|
EmbeddingContext context = EmbeddingContext.builder()
|
||||||
.vectorSourceId(knowledge.getVectorSourceId())
|
.vectorSourceId(knowledge.getVectorSourceId())
|
||||||
.groupId(groupId)
|
.groupId(groupId)
|
||||||
@@ -77,13 +81,16 @@ public class EmbeddingService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submit(Long id, String mode, ImmutableList<String> ids) {
|
public void submit(Long id, String mode, ImmutableList<Long> ids) {
|
||||||
executors.submit(() -> {
|
executors.submit(() -> {
|
||||||
Knowledge knowledge = knowledgeBaseService.get(id);
|
Knowledge knowledge = knowledgeBaseService.detailOrThrow(id);
|
||||||
List<Pair<Long, DataFile>> dataFiles = Lists.mutable.empty();
|
List<Pair<Long, DataFile>> dataFiles = Lists.mutable.empty();
|
||||||
for (String fileId : ids) {
|
for (Long fileId : ids) {
|
||||||
DataFile dataFile = dataFileService.downloadFile(Long.parseLong(fileId));
|
DataFile dataFile = dataFileService.downloadFile(fileId);
|
||||||
Long groupId = groupService.add(id, dataFile.getFilename());
|
Group group = new Group();
|
||||||
|
group.setName(dataFile.getFilename());
|
||||||
|
group.setKnowledge(knowledge);
|
||||||
|
Long groupId = groupService.save(group);
|
||||||
dataFiles.add(Pair.of(groupId, dataFile));
|
dataFiles.add(Pair.of(groupId, dataFile));
|
||||||
}
|
}
|
||||||
for (Pair<Long, DataFile> pair : dataFiles) {
|
for (Pair<Long, DataFile> pair : dataFiles) {
|
||||||
@@ -106,12 +113,15 @@ public class EmbeddingService {
|
|||||||
|
|
||||||
public void submitDirectly(Long id, String name, ImmutableList<String> contents) {
|
public void submitDirectly(Long id, String name, ImmutableList<String> contents) {
|
||||||
executors.submit(() -> {
|
executors.submit(() -> {
|
||||||
Knowledge knowledge = knowledgeBaseService.get(id);
|
Knowledge knowledge = knowledgeBaseService.detailOrThrow(id);
|
||||||
String groupName = name;
|
String groupName = name;
|
||||||
if (StrUtil.isBlank(groupName)) {
|
if (StrUtil.isBlank(groupName)) {
|
||||||
groupName = StrUtil.format("外部-{}", IdUtil.nanoId(10));
|
groupName = StrUtil.format("外部-{}", IdUtil.nanoId(10));
|
||||||
}
|
}
|
||||||
Long groupId = groupService.add(knowledge.getId(), groupName);
|
Group group = new Group();
|
||||||
|
group.setName(groupName);
|
||||||
|
group.setKnowledge(knowledge);
|
||||||
|
Long groupId = groupService.save(group);
|
||||||
EmbeddingContext context = EmbeddingContext.builder()
|
EmbeddingContext context = EmbeddingContext.builder()
|
||||||
.vectorSourceId(knowledge.getVectorSourceId())
|
.vectorSourceId(knowledge.getVectorSourceId())
|
||||||
.groupId(groupId)
|
.groupId(groupId)
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import com.lanyuanxiaoyao.service.ai.web.entity.context.FeedbackContext;
|
|||||||
import com.lanyuanxiaoyao.service.ai.web.repository.FeedbackRepository;
|
import com.lanyuanxiaoyao.service.ai.web.repository.FeedbackRepository;
|
||||||
import com.yomahub.liteflow.core.FlowExecutor;
|
import com.yomahub.liteflow.core.FlowExecutor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -22,7 +24,7 @@ public class FeedbackService extends SimpleServiceSupport<Feedback> {
|
|||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Scheduled(initialDelay = 1, fixedDelay = 1, timeUnit = TimeUnit.MINUTES)
|
@Scheduled(initialDelay = 1, fixedDelay = 1, timeUnit = TimeUnit.MINUTES)
|
||||||
public void analysis() {
|
public void analysis() {
|
||||||
List<Feedback> feedbacks = repository.findAll(
|
List<Feedback> feedbacks = repository.findAll(
|
||||||
builder -> builder
|
builder -> builder
|
||||||
|
|||||||
@@ -1,21 +1,14 @@
|
|||||||
package com.lanyuanxiaoyao.service.ai.web.service.knowledge;
|
package com.lanyuanxiaoyao.service.ai.web.service.knowledge;
|
||||||
|
|
||||||
import club.kingon.sql.builder.SqlBuilder;
|
import com.lanyuanxiaoyao.service.ai.web.base.service.SimpleServiceSupport;
|
||||||
import club.kingon.sql.builder.entry.Alias;
|
|
||||||
import club.kingon.sql.builder.entry.Column;
|
|
||||||
import com.lanyuanxiaoyao.service.ai.core.configuration.SnowflakeId;
|
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.Group;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Group;
|
||||||
import com.lanyuanxiaoyao.service.common.Constants;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Knowledge;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.repository.GroupRepository;
|
||||||
import io.qdrant.client.ConditionFactory;
|
import io.qdrant.client.ConditionFactory;
|
||||||
import io.qdrant.client.QdrantClient;
|
import io.qdrant.client.QdrantClient;
|
||||||
import io.qdrant.client.grpc.Points;
|
import io.qdrant.client.grpc.Points;
|
||||||
import java.util.concurrent.ExecutionException;
|
import lombok.SneakyThrows;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.eclipse.collections.api.factory.Lists;
|
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
import org.springframework.ai.vectorstore.VectorStore;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -24,107 +17,34 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
* @version 20250522
|
* @version 20250522
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class GroupService {
|
public class GroupService extends SimpleServiceSupport<Group> {
|
||||||
public static final String GROUP_TABLE_NAME = Constants.DATABASE_NAME + ".service_ai_group";
|
|
||||||
private static final RowMapper<Group> groupMapper = (rs, row) -> {
|
|
||||||
Group vo = new Group();
|
|
||||||
vo.setId(rs.getLong(1));
|
|
||||||
vo.setName(rs.getString(2));
|
|
||||||
vo.setStatus(rs.getString(3));
|
|
||||||
return vo;
|
|
||||||
};
|
|
||||||
|
|
||||||
private final JdbcTemplate template;
|
|
||||||
private final QdrantClient client;
|
private final QdrantClient client;
|
||||||
|
|
||||||
public GroupService(JdbcTemplate template, VectorStore vectorStore) {
|
public GroupService(GroupRepository groupRepository, VectorStore vectorStore) {
|
||||||
this.template = template;
|
super(groupRepository);
|
||||||
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group get(Long id) {
|
|
||||||
return template.queryForObject(
|
|
||||||
SqlBuilder.select("id", "name", "status", "created_time", "modified_time")
|
|
||||||
.from(GROUP_TABLE_NAME)
|
|
||||||
.whereEq("id", id)
|
|
||||||
.orderByDesc("created_time")
|
|
||||||
.build(),
|
|
||||||
groupMapper
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long add(Long knowledgeId, String name) {
|
public void finish(Long id) {
|
||||||
long id = SnowflakeId.next();
|
Group group = detailOrThrow(id);
|
||||||
template.update(
|
group.setStatus(Group.Status.FINISHED);
|
||||||
SqlBuilder.insertInto(GROUP_TABLE_NAME, "id", "knowledge_id", "name", "status")
|
save(group);
|
||||||
.values()
|
|
||||||
.addValue("?", "?", "?", "?")
|
|
||||||
.precompileSql(),
|
|
||||||
id,
|
|
||||||
knowledgeId,
|
|
||||||
name,
|
|
||||||
"RUNNING"
|
|
||||||
);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ImmutableList<Group> list(Long knowledgeId) {
|
|
||||||
return template.query(
|
|
||||||
SqlBuilder.select("id", "name", "status", "created_time", "modified_time")
|
|
||||||
.from(GROUP_TABLE_NAME)
|
|
||||||
.whereEq("knowledge_id", knowledgeId)
|
|
||||||
.orderByDesc("created_time")
|
|
||||||
.build(),
|
|
||||||
groupMapper
|
|
||||||
)
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toCollection(Lists.mutable::empty))
|
|
||||||
.toImmutable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void finish(Long groupId) {
|
@Override
|
||||||
template.update(
|
public void remove(Long id) {
|
||||||
SqlBuilder.update(GROUP_TABLE_NAME)
|
Group group = detailOrThrow(id);
|
||||||
.set("status", "FINISHED")
|
Knowledge knowledge = group.getKnowledge();
|
||||||
.whereEq("id", groupId)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void remove(Long groupId) throws ExecutionException, InterruptedException {
|
|
||||||
Long vectorSourceId = template.queryForObject(
|
|
||||||
SqlBuilder.select("k.vector_source_id")
|
|
||||||
.from(Alias.of(GROUP_TABLE_NAME, "g"), Alias.of(KnowledgeBaseService.KNOWLEDGE_TABLE_NAME, "k"))
|
|
||||||
.whereEq("g.knowledge_id", Column.as("k.id"))
|
|
||||||
.andEq("g.id", groupId)
|
|
||||||
.precompileSql(),
|
|
||||||
Long.class,
|
|
||||||
groupId
|
|
||||||
);
|
|
||||||
client.deleteAsync(
|
client.deleteAsync(
|
||||||
String.valueOf(vectorSourceId),
|
String.valueOf(knowledge.getVectorSourceId()),
|
||||||
Points.Filter.newBuilder()
|
Points.Filter.newBuilder()
|
||||||
.addMust(ConditionFactory.matchKeyword("vector_source_id", String.valueOf(vectorSourceId)))
|
.addMust(ConditionFactory.matchKeyword("vector_source_id", String.valueOf(knowledge.getVectorSourceId())))
|
||||||
.addMust(ConditionFactory.matchKeyword("group_id", String.valueOf(groupId)))
|
.addMust(ConditionFactory.matchKeyword("group_id", String.valueOf(group.getId())))
|
||||||
.build()
|
.build()
|
||||||
).get();
|
).get();
|
||||||
template.update(
|
super.remove(id);
|
||||||
SqlBuilder.delete(GROUP_TABLE_NAME)
|
|
||||||
.whereEq("id", groupId)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void removeByKnowledgeId(Long knowledgeId) {
|
|
||||||
template.update(
|
|
||||||
SqlBuilder.delete(GROUP_TABLE_NAME)
|
|
||||||
.whereEq("knowledge_id", "?")
|
|
||||||
.precompileSql(),
|
|
||||||
knowledgeId
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ package com.lanyuanxiaoyao.service.ai.web.service.knowledge;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.base.service.SimpleServiceSupport;
|
import com.lanyuanxiaoyao.service.ai.web.base.service.SimpleServiceSupport;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.configuration.SnowflakeIdGenerator;
|
import com.lanyuanxiaoyao.service.ai.web.configuration.SnowflakeIdGenerator;
|
||||||
|
import com.lanyuanxiaoyao.service.ai.web.entity.Group;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.entity.Knowledge;
|
import com.lanyuanxiaoyao.service.ai.web.entity.Knowledge;
|
||||||
import com.lanyuanxiaoyao.service.ai.web.repository.KnowledgeRepository;
|
import com.lanyuanxiaoyao.service.ai.web.repository.KnowledgeRepository;
|
||||||
import com.lanyuanxiaoyao.service.common.Constants;
|
import com.lanyuanxiaoyao.service.common.Constants;
|
||||||
|
import io.qdrant.client.ConditionFactory;
|
||||||
import io.qdrant.client.QdrantClient;
|
import io.qdrant.client.QdrantClient;
|
||||||
import io.qdrant.client.grpc.Collections;
|
import io.qdrant.client.grpc.Collections;
|
||||||
|
import io.qdrant.client.grpc.Points;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
import org.eclipse.collections.api.factory.Lists;
|
import org.eclipse.collections.api.factory.Lists;
|
||||||
import org.eclipse.collections.api.list.ImmutableList;
|
import org.eclipse.collections.api.list.ImmutableList;
|
||||||
import org.springframework.ai.document.Document;
|
import org.springframework.ai.document.Document;
|
||||||
@@ -17,7 +21,6 @@ import org.springframework.ai.embedding.EmbeddingModel;
|
|||||||
import org.springframework.ai.vectorstore.SearchRequest;
|
import org.springframework.ai.vectorstore.SearchRequest;
|
||||||
import org.springframework.ai.vectorstore.VectorStore;
|
import org.springframework.ai.vectorstore.VectorStore;
|
||||||
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
|
import org.springframework.ai.vectorstore.qdrant.QdrantVectorStore;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@@ -28,16 +31,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
@Service
|
@Service
|
||||||
public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
||||||
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) -> {
|
|
||||||
Knowledge knowledge = new Knowledge();
|
|
||||||
knowledge.setId(rs.getLong(1));
|
|
||||||
knowledge.setVectorSourceId(rs.getLong(2));
|
|
||||||
knowledge.setName(rs.getString(3));
|
|
||||||
knowledge.setDescription(rs.getString(4));
|
|
||||||
knowledge.setStrategy(rs.getString(5));
|
|
||||||
return knowledge;
|
|
||||||
};
|
|
||||||
private final KnowledgeRepository knowledgeRepository;
|
private final KnowledgeRepository knowledgeRepository;
|
||||||
private final EmbeddingModel model;
|
private final EmbeddingModel model;
|
||||||
private final QdrantClient client;
|
private final QdrantClient client;
|
||||||
@@ -49,8 +42,9 @@ public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
|||||||
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long save(Knowledge entity) throws Exception {
|
public Long save(Knowledge entity) {
|
||||||
if (knowledgeRepository.existsKnowledgeByName(entity.getName())) {
|
if (knowledgeRepository.existsKnowledgeByName(entity.getName())) {
|
||||||
throw new RuntimeException("名称已存在");
|
throw new RuntimeException("名称已存在");
|
||||||
}
|
}
|
||||||
@@ -59,7 +53,7 @@ public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
|||||||
client.createCollectionAsync(
|
client.createCollectionAsync(
|
||||||
String.valueOf(vectorSourceId),
|
String.valueOf(vectorSourceId),
|
||||||
Collections.VectorParams.newBuilder()
|
Collections.VectorParams.newBuilder()
|
||||||
.setDistance(Collections.Distance.valueOf(entity.getStrategy()))
|
.setDistance(Collections.Distance.valueOf(entity.getStrategy().name()))
|
||||||
.setSize(model.dimensions())
|
.setSize(model.dimensions())
|
||||||
.build()
|
.build()
|
||||||
).get();
|
).get();
|
||||||
@@ -79,11 +73,21 @@ public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
|||||||
return detailOrThrow(id).getName();
|
return detailOrThrow(id).getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
@Override
|
||||||
public void remove(Long id) throws Exception {
|
public void remove(Long id) {
|
||||||
Knowledge knowledge = detailOrThrow(id);
|
Knowledge knowledge = detailOrThrow(id);
|
||||||
client.deleteCollectionAsync(String.valueOf(knowledge.getVectorSourceId())).get();
|
client.deleteCollectionAsync(String.valueOf(knowledge.getVectorSourceId())).get();
|
||||||
|
for (Group group : knowledge.getGroups()) {
|
||||||
|
client.deleteAsync(
|
||||||
|
String.valueOf(knowledge.getVectorSourceId()),
|
||||||
|
Points.Filter.newBuilder()
|
||||||
|
.addMust(ConditionFactory.matchKeyword("vector_source_id", String.valueOf(knowledge.getVectorSourceId())))
|
||||||
|
.addMust(ConditionFactory.matchKeyword("group_id", String.valueOf(group.getId())))
|
||||||
|
.build()
|
||||||
|
).get();
|
||||||
|
}
|
||||||
super.remove(id);
|
super.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +117,7 @@ public class KnowledgeBaseService extends SimpleServiceSupport<Knowledge> {
|
|||||||
.collect(Document::getText);
|
.collect(Document::getText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collections.CollectionInfo getCollectionInfoById(Long vectorSourceId) throws ExecutionException, InterruptedException {
|
public Collections.CollectionInfo collectionInfo(Long vectorSourceId) throws ExecutionException, InterruptedException {
|
||||||
return client.getCollectionInfoAsync(String.valueOf(vectorSourceId)).get();
|
return client.getCollectionInfoAsync(String.valueOf(vectorSourceId)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,8 @@ public class SegmentService {
|
|||||||
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
this.client = (QdrantClient) vectorStore.getNativeClient().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImmutableList<SegmentVO> list(Long id, Long groupId) throws ExecutionException, InterruptedException {
|
public ImmutableList<SegmentVO> list(Long knowledgeId, Long groupId) throws ExecutionException, InterruptedException {
|
||||||
Knowledge knowledge = knowledgeBaseService.get(id);
|
Knowledge knowledge = knowledgeBaseService.detailOrThrow(knowledgeId);
|
||||||
Points.ScrollResponse response = client.scrollAsync(
|
Points.ScrollResponse response = client.scrollAsync(
|
||||||
Points.ScrollPoints.newBuilder()
|
Points.ScrollPoints.newBuilder()
|
||||||
.setCollectionName(String.valueOf(knowledge.getVectorSourceId()))
|
.setCollectionName(String.valueOf(knowledge.getVectorSourceId()))
|
||||||
@@ -55,7 +55,7 @@ public class SegmentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void remove(Long knowledgeId, Long segmentId) throws ExecutionException, InterruptedException {
|
public void remove(Long knowledgeId, Long segmentId) throws ExecutionException, InterruptedException {
|
||||||
Knowledge knowledge = knowledgeBaseService.get(knowledgeId);
|
Knowledge knowledge = knowledgeBaseService.detailOrThrow(knowledgeId);
|
||||||
client.deletePayloadAsync(
|
client.deletePayloadAsync(
|
||||||
String.valueOf(knowledgeId),
|
String.valueOf(knowledgeId),
|
||||||
List.of(String.valueOf(segmentId)),
|
List.of(String.valueOf(segmentId)),
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
server:
|
server:
|
||||||
compression:
|
compression:
|
||||||
enabled: true
|
enabled: true
|
||||||
port: 8080
|
|
||||||
spring:
|
spring:
|
||||||
application:
|
application:
|
||||||
name: service-ai-web
|
name: service-ai-web
|
||||||
profiles:
|
profiles:
|
||||||
include: common,forest
|
include: random-port,common,discovery,metrics,forest
|
||||||
mvc:
|
mvc:
|
||||||
async:
|
async:
|
||||||
request-timeout: 3600000
|
request-timeout: 3600000
|
||||||
@@ -22,47 +21,27 @@ spring:
|
|||||||
ai:
|
ai:
|
||||||
vectorstore:
|
vectorstore:
|
||||||
qdrant:
|
qdrant:
|
||||||
|
host: 132.121.206.65
|
||||||
|
port: 29463
|
||||||
api-key: ENC(0/0UkIKeAvyV17yNqSU3v04wmm8CdWKe4BYSSJa2FuBtK12TcZRJPdwk+ZpYnpISv+KmVTUrrmFBzAYrDR3ysA==)
|
api-key: ENC(0/0UkIKeAvyV17yNqSU3v04wmm8CdWKe4BYSSJa2FuBtK12TcZRJPdwk+ZpYnpISv+KmVTUrrmFBzAYrDR3ysA==)
|
||||||
host: 192.168.100.140
|
|
||||||
port: 6334
|
|
||||||
llm:
|
llm:
|
||||||
base-url: https://api.siliconflow.cn
|
base-url: http://132.121.206.65:10086
|
||||||
api-key: sk-xrguybusoqndpqvgzgvllddzgjamksuecyqdaygdwnrnqfwo
|
api-key: ENC(K+Hff9QGC+fcyi510VIDd9CaeK/IN5WBJ9rlkUsHEdDgIidW+stHHJlsK0lLPUXXREha+ToQZqqDXJrqSE+GUKCXklFhelD8bRHFXBIeP/ZzT2cxhzgKUXgjw3S0Qw2R)
|
||||||
chat:
|
chat:
|
||||||
base-url: ${spring.llm.base-url}/v1
|
base-url: ${spring.llm.base-url}/v1
|
||||||
model: 'Qwen/Qwen3-8B'
|
model: 'Qwen3/qwen3-1.7b'
|
||||||
visual:
|
visual:
|
||||||
base-url: https://open.bigmodel.cn/api/paas/v4
|
model: 'Qwen2.5/qwen2.5-vl-7b-q4km'
|
||||||
endpoint: /chat/completions
|
|
||||||
model: 'glm-4v-flash'
|
|
||||||
embedding:
|
embedding:
|
||||||
model: 'BAAI/bge-m3'
|
model: 'Qwen3/qwen3-embedding-4b'
|
||||||
reranker:
|
reranker:
|
||||||
model: 'BAAI/bge-reranker-v2-m3'
|
model: 'BGE/beg-reranker-v2'
|
||||||
cloud:
|
|
||||||
discovery:
|
|
||||||
enabled: false
|
|
||||||
zookeeper:
|
|
||||||
enabled: false
|
|
||||||
datasource:
|
|
||||||
url: jdbc:mysql://192.168.100.140:3306/hudi_collect_build_b12?useSSL=false&allowPublicKeyRetrieval=true
|
|
||||||
username: root
|
|
||||||
password: rootless
|
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
|
||||||
security:
|
|
||||||
meta:
|
|
||||||
authority: ENC(GXKnbq1LS11U2HaONspvH+D/TkIx13aWTaokdkzaF7HSvq6Z0Rv1+JUWFnYopVXu)
|
|
||||||
username: ENC(moIO5mO39V1Z+RDwROK9JXY4GfM8ZjDgM6Si7wRZ1MPVjbhTpmLz3lz28rAiw7c2LeCmizfJzHkEXIwGlB280g==)
|
|
||||||
darkcode: ENC(0jzpQ7T6S+P7bZrENgYsUoLhlqGvw7DA2MN3BRqEOwq7plhtg72vuuiPQNnr3DaYz0CpyTvxInhpx11W3VZ1trD6NINh7O3LN70ZqO5pWXk=)
|
|
||||||
jpa:
|
jpa:
|
||||||
show-sql: true
|
show-sql: true
|
||||||
generate-ddl: true
|
generate-ddl: false
|
||||||
liteflow:
|
liteflow:
|
||||||
rule-source: liteflow.xml
|
rule-source: liteflow.xml
|
||||||
print-banner: false
|
print-banner: false
|
||||||
check-node-exists: false
|
check-node-exists: false
|
||||||
jasypt:
|
|
||||||
encryptor:
|
|
||||||
password: 'r#(R,P"Dp^A47>WSn:Wn].gs/+"v:q_Q*An~zF*g-@j@jtSTv5H/,S-3:R?r9R}.'
|
|
||||||
fenix:
|
fenix:
|
||||||
print-banner: false
|
print-banner: false
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
<logger name="com.zaxxer.hikari" level="ERROR"/>
|
||||||
<logger name="com.netflix.discovery.shared.resolver.aws.ConfigClusterResolver" level="WARN"/>
|
<logger name="org.hibernate.SQL" level="DEBUG"/>
|
||||||
|
|
||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
<appender-ref ref="Console"/>
|
<appender-ref ref="Console"/>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const DataDetail: React.FC = () => {
|
|||||||
{
|
{
|
||||||
type: 'service',
|
type: 'service',
|
||||||
className: 'inline',
|
className: 'inline',
|
||||||
api: `${commonInfo.baseAiUrl}/knowledge/name?id=${knowledge_id}`,
|
api: `${commonInfo.baseAiUrl}/knowledge/${knowledge_id}/name`,
|
||||||
body: {
|
body: {
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '${name}',
|
tpl: '${name}',
|
||||||
@@ -38,7 +38,21 @@ const DataDetail: React.FC = () => {
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'crud',
|
type: 'crud',
|
||||||
api: `${commonInfo.baseAiUrl}/knowledge/group/list?knowledge_id=${knowledge_id}`,
|
api: {
|
||||||
|
method: 'post',
|
||||||
|
url: `${commonInfo.baseAiUrl}/knowledge/group/list`,
|
||||||
|
data: {
|
||||||
|
query: {
|
||||||
|
equal: {
|
||||||
|
'knowledge/id': knowledge_id,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
index: '${page}',
|
||||||
|
size: '${perPage}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
...crudCommonOptions(),
|
...crudCommonOptions(),
|
||||||
headerToolbar: [
|
headerToolbar: [
|
||||||
'reload',
|
'reload',
|
||||||
@@ -146,7 +160,7 @@ const DataDetail: React.FC = () => {
|
|||||||
level: 'link',
|
level: 'link',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
actionType: 'ajax',
|
actionType: 'ajax',
|
||||||
api: `get:${commonInfo.baseAiUrl}/knowledge/group/delete?id=\${id}`,
|
api: `get:${commonInfo.baseAiUrl}/knowledge/group/remove/\${id}`,
|
||||||
confirmText: '确认删除',
|
confirmText: '确认删除',
|
||||||
confirmTitle: '删除',
|
confirmTitle: '删除',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const DataImport: React.FC = () => {
|
|||||||
{
|
{
|
||||||
type: 'service',
|
type: 'service',
|
||||||
className: 'inline',
|
className: 'inline',
|
||||||
api: `${commonInfo.baseAiUrl}/knowledge/name?id=${knowledge_id}`,
|
api: `${commonInfo.baseAiUrl}/knowledge/${knowledge_id}/name`,
|
||||||
body: {
|
body: {
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '${name}',
|
tpl: '${name}',
|
||||||
@@ -42,6 +42,7 @@ const DataImport: React.FC = () => {
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
id: 'a5219cc7-72dd-4199-9eeb-61305fe41075',
|
id: 'a5219cc7-72dd-4199-9eeb-61305fe41075',
|
||||||
|
debug: commonInfo.debug,
|
||||||
type: 'form',
|
type: 'form',
|
||||||
wrapWithPanel: false,
|
wrapWithPanel: false,
|
||||||
actions: [],
|
actions: [],
|
||||||
@@ -103,6 +104,8 @@ const DataImport: React.FC = () => {
|
|||||||
autoUpload: false,
|
autoUpload: false,
|
||||||
drag: true,
|
drag: true,
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
joinValues: false,
|
||||||
|
extractValue: true,
|
||||||
accept: '*',
|
accept: '*',
|
||||||
// 5MB 5242880
|
// 5MB 5242880
|
||||||
// 100MB 104857600
|
// 100MB 104857600
|
||||||
@@ -131,7 +134,6 @@ const DataImport: React.FC = () => {
|
|||||||
api: {
|
api: {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: `${commonInfo.baseAiUrl}/knowledge/preview_text`,
|
url: `${commonInfo.baseAiUrl}/knowledge/preview_text`,
|
||||||
dataType: 'form',
|
|
||||||
data: {
|
data: {
|
||||||
mode: '${mode|default:undefined}',
|
mode: '${mode|default:undefined}',
|
||||||
type: '${type|default:undefined}',
|
type: '${type|default:undefined}',
|
||||||
@@ -149,7 +151,6 @@ const DataImport: React.FC = () => {
|
|||||||
api: {
|
api: {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: `${commonInfo.baseAiUrl}/knowledge/submit_text`,
|
url: `${commonInfo.baseAiUrl}/knowledge/submit_text`,
|
||||||
dataType: 'form',
|
|
||||||
data: {
|
data: {
|
||||||
id: knowledge_id,
|
id: knowledge_id,
|
||||||
mode: '${mode|default:undefined}',
|
mode: '${mode|default:undefined}',
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const DataDetail: React.FC = () => {
|
|||||||
{
|
{
|
||||||
type: 'service',
|
type: 'service',
|
||||||
className: 'inline',
|
className: 'inline',
|
||||||
api: `${commonInfo.baseAiUrl}/knowledge/name?id=${knowledge_id}`,
|
api: `${commonInfo.baseAiUrl}/knowledge/${knowledge_id}/name`,
|
||||||
body: {
|
body: {
|
||||||
type: 'tpl',
|
type: 'tpl',
|
||||||
tpl: '${name}',
|
tpl: '${name}',
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {useNavigate} from 'react-router'
|
import {useNavigate} from 'react-router'
|
||||||
import {amisRender, commonInfo, crudCommonOptions, mappingField, mappingItem} from '../../../util/amis.tsx'
|
import {
|
||||||
|
amisRender,
|
||||||
|
commonInfo,
|
||||||
|
crudCommonOptions,
|
||||||
|
mappingField,
|
||||||
|
mappingItem,
|
||||||
|
paginationTemplate,
|
||||||
|
} from '../../../util/amis.tsx'
|
||||||
|
|
||||||
const strategyMapping = [
|
const strategyMapping = [
|
||||||
mappingItem('文本', 'Cosine'),
|
mappingItem('文本', 'Cosine'),
|
||||||
@@ -25,10 +32,21 @@ const Knowledge: React.FC = () => {
|
|||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'crud',
|
type: 'crud',
|
||||||
api: `${commonInfo.baseAiUrl}/knowledge/list`,
|
api: {
|
||||||
|
method: 'post',
|
||||||
|
url: `${commonInfo.baseAiUrl}/knowledge/list`,
|
||||||
|
data: {
|
||||||
|
page: {
|
||||||
|
index: '${page}',
|
||||||
|
size: '${perPage}',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
...crudCommonOptions(),
|
...crudCommonOptions(),
|
||||||
headerToolbar: [
|
...paginationTemplate(
|
||||||
'reload',
|
10,
|
||||||
|
5,
|
||||||
|
[
|
||||||
{
|
{
|
||||||
type: 'action',
|
type: 'action',
|
||||||
label: '',
|
label: '',
|
||||||
@@ -42,8 +60,8 @@ const Knowledge: React.FC = () => {
|
|||||||
body: {
|
body: {
|
||||||
type: 'form',
|
type: 'form',
|
||||||
api: {
|
api: {
|
||||||
url: `${commonInfo.baseAiUrl}/knowledge/add`,
|
method: 'post',
|
||||||
dataType: 'form',
|
url: `${commonInfo.baseAiUrl}/knowledge/save`,
|
||||||
},
|
},
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
@@ -81,6 +99,7 @@ const Knowledge: React.FC = () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
),
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
name: 'name',
|
name: 'name',
|
||||||
@@ -128,13 +147,12 @@ const Knowledge: React.FC = () => {
|
|||||||
api: {
|
api: {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: `${commonInfo.baseAiUrl}/knowledge/update_description`,
|
url: `${commonInfo.baseAiUrl}/knowledge/update_description`,
|
||||||
dataType: 'form',
|
|
||||||
},
|
},
|
||||||
mode: 'normal',
|
mode: 'normal',
|
||||||
body: [
|
body: [
|
||||||
{
|
{
|
||||||
type: 'hidden',
|
type: 'hidden',
|
||||||
name: "id",
|
name: 'id',
|
||||||
// value: '${id}',
|
// value: '${id}',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -142,10 +160,10 @@ const Knowledge: React.FC = () => {
|
|||||||
name: 'description',
|
name: 'description',
|
||||||
label: '描述',
|
label: '描述',
|
||||||
required: true,
|
required: true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'action',
|
type: 'action',
|
||||||
@@ -192,17 +210,8 @@ const Knowledge: React.FC = () => {
|
|||||||
level: 'link',
|
level: 'link',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
actionType: 'ajax',
|
actionType: 'ajax',
|
||||||
api: {
|
api: `get:${commonInfo.baseAiUrl}/knowledge/remove/\${id}`,
|
||||||
method: 'get',
|
confirmText: '确认删除知识库:${name}',
|
||||||
url: `${commonInfo.baseAiUrl}/knowledge/delete`,
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
id: '${id}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
confirmText: '确认删除',
|
|
||||||
confirmTitle: '删除',
|
confirmTitle: '删除',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import {isEqual} from 'licia'
|
|||||||
export const commonInfo = {
|
export const commonInfo = {
|
||||||
debug: isEqual(import.meta.env.MODE, 'development'),
|
debug: isEqual(import.meta.env.MODE, 'development'),
|
||||||
baseUrl: 'http://132.126.207.130:35690/hudi_services/service_web',
|
baseUrl: 'http://132.126.207.130:35690/hudi_services/service_web',
|
||||||
// baseAiUrl: 'http://132.126.207.130:35690/hudi_services/service_ai_web',
|
baseAiUrl: 'http://132.126.207.130:35690/hudi_services/service_ai_web',
|
||||||
baseAiUrl: 'http://localhost:8080',
|
// baseAiUrl: 'http://localhost:8080',
|
||||||
authorizationHeaders: {
|
authorizationHeaders: {
|
||||||
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
'Authorization': 'Basic QXhoRWJzY3dzSkRiWU1IMjpjWXhnM2I0UHRXb1ZENVNqRmF5V3h0blNWc2p6UnNnNA==',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -311,16 +311,18 @@ export function paginationCommonOptions(perPage = true, maxButtons = 5) {
|
|||||||
return option
|
return option
|
||||||
}
|
}
|
||||||
|
|
||||||
export function paginationTemplate(perPage = 20, maxButtons = 5) {
|
export function paginationTemplate(perPage = 20, maxButtons = 5, extraHeaders: Schema[] = [], extraFooters: Schema[] = []) {
|
||||||
return {
|
return {
|
||||||
perPage: perPage,
|
perPage: perPage,
|
||||||
headerToolbar: [
|
headerToolbar: [
|
||||||
'reload',
|
'reload',
|
||||||
paginationCommonOptions(true, maxButtons),
|
paginationCommonOptions(true, maxButtons),
|
||||||
|
...extraHeaders,
|
||||||
],
|
],
|
||||||
footerToolbar: [
|
footerToolbar: [
|
||||||
'statistics',
|
'statistics',
|
||||||
paginationCommonOptions(true, maxButtons),
|
paginationCommonOptions(true, maxButtons),
|
||||||
|
...extraFooters,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user