增加:管理员->大语言模型模块接口

This commit is contained in:
moyangzhan 2024-06-05 19:48:08 +08:00
parent 6362d10c6b
commit 8076c0cafa
16 changed files with 163 additions and 36 deletions

View File

@ -1,6 +1,7 @@
package com.moyz.adi.admin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moyz.adi.common.dto.KbEditReq;
import com.moyz.adi.common.dto.KbInfoResp;
import com.moyz.adi.common.dto.KbSearchReq;
import com.moyz.adi.common.service.KnowledgeBaseService;
@ -8,10 +9,7 @@ import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
/**
* Knowledge Base
@ -28,4 +26,14 @@ public class AdminKbController {
public Page<KbInfoResp> search(@RequestBody KbSearchReq kbSearchReq, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return knowledgeBaseService.search(kbSearchReq, currentPage, pageSize);
}
@PostMapping("/delete/{uuid}")
public boolean delete(@PathVariable String uuid) {
return knowledgeBaseService.softDelete(uuid);
}
@PostMapping("/edit")
public boolean edit(@RequestBody KbEditReq kbEditReq) {
return knowledgeBaseService.updateKb(kbEditReq);
}
}

View File

@ -2,13 +2,21 @@ package com.moyz.adi.admin.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moyz.adi.common.dto.AiModelDto;
import com.moyz.adi.common.dto.AiModelSearchReq;
import com.moyz.adi.common.exception.BaseException;
import com.moyz.adi.common.interfaces.AiModelAddGroup;
import com.moyz.adi.common.interfaces.AiModelEditGroup;
import com.moyz.adi.common.service.AiModelService;
import com.moyz.adi.common.util.AiModelUtil;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import static com.moyz.adi.common.enums.ErrorEnum.A_PARAMS_ERROR;
@RestController
@RequestMapping("/admin/model")
@Validated
@ -17,23 +25,34 @@ public class AdminModelController {
@Resource
private AiModelService aiModelService;
@GetMapping("/list")
public Page<AiModelDto> page(@RequestParam String platform, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return aiModelService.page(platform, currentPage, pageSize);
@PostMapping("/list")
public Page<AiModelDto> page(@RequestBody AiModelSearchReq aiModelSearchReq, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return aiModelService.page(aiModelSearchReq, currentPage, pageSize);
}
@PostMapping("/disable/{id}")
public void disable(@PathVariable Long id) {
aiModelService.disable(id);
@PostMapping("/addOne")
public AiModelDto addOne(@Validated(AiModelAddGroup.class) @RequestBody AiModelDto aiModelDto) {
check(aiModelDto.getPlatform(), aiModelDto.getType());
return aiModelService.addOne(aiModelDto);
}
@PostMapping("/enable/{id}")
public void enable(@PathVariable Long id) {
aiModelService.enable(id);
@PostMapping("/edit")
public void edit(@Validated(AiModelEditGroup.class) @RequestBody AiModelDto aiModelDto) {
check(aiModelDto.getPlatform(), aiModelDto.getType());
aiModelService.edit(aiModelDto);
}
@PostMapping("/delete/{id}")
public void delete(@PathVariable Long id) {
aiModelService.softDelete(id);
}
private void check(String platform, String type) {
if (StringUtils.isNotBlank(platform) && !AiModelUtil.checkModelPlatform(platform)) {
throw new BaseException(A_PARAMS_ERROR);
}
if (StringUtils.isNotBlank(type) && !AiModelUtil.checkModelType(type)) {
throw new BaseException(A_PARAMS_ERROR);
}
}
}

View File

@ -19,8 +19,8 @@ public class SystemConfigController {
@Resource
private SysConfigService sysConfigService;
@GetMapping("/list")
public Page<SysConfig> list(@RequestParam String keyword, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
@GetMapping("/search")
public Page<SysConfig> search(@RequestParam String keyword, @NotNull @Min(1) Integer currentPage, @NotNull @Min(10) Integer pageSize) {
return sysConfigService.search(keyword, currentPage, pageSize);
}

View File

@ -1,24 +1,36 @@
package com.moyz.adi.common.dto;
import com.moyz.adi.common.interfaces.AiModelAddGroup;
import com.moyz.adi.common.interfaces.AiModelEditGroup;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
@Validated
@Data
public class AiModelDto {
@NotNull(groups = AiModelEditGroup.class)
private Long id;
@NotBlank(groups = AiModelAddGroup.class)
private String type;
@NotBlank(groups = AiModelAddGroup.class)
private String name;
@NotBlank(groups = AiModelAddGroup.class)
private String platform;
private String remark;
private Boolean isEnable;
private Integer contextWindow;
private LocalDateTime createTime;
private LocalDateTime updateTime;

View File

@ -0,0 +1,10 @@
package com.moyz.adi.common.dto;
import lombok.Data;
@Data
public class AiModelSearchReq {
private String type;
private String platform;
private Boolean isEnable;
}

View File

@ -10,6 +10,8 @@ public class UserEditReq {
private String name;
private String password;
private UserStatusEnum userStatus;
private Integer quotaByTokenDaily;

View File

@ -29,4 +29,8 @@ public class AiModel extends BaseEntity {
@Schema(title = "状态(1:正常使用,0:不可用)")
@TableField("is_enable")
private Boolean isEnable;
@Schema(title = "上下文长度")
@TableField("context_window")
private Integer contextWindow;
}

View File

@ -24,6 +24,7 @@ public enum ErrorEnum {
A_QA_ITEM_LIMIT("A0020", "知识点生成已超额度"),
A_CONVERSATION_EXIST("A0021", "对话已存在"),
A_MODEL_NOT_FOUND("A0022", "模型不存在"),
A_MODEL_ALREADY_EXIST("A0023", "模型已存在"),
B_UNCAUGHT_ERROR("B0001", "未捕捉异常"),
B_COMMON_ERROR("B0002", "业务出错"),
B_GLOBAL_ERROR("B0003", "全局异常"),

View File

@ -0,0 +1,4 @@
package com.moyz.adi.common.interfaces;
public interface AiModelAddGroup {
}

View File

@ -0,0 +1,4 @@
package com.moyz.adi.common.interfaces;
public interface AiModelEditGroup {
}

View File

@ -1,25 +1,22 @@
package com.moyz.adi.common.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.moyz.adi.common.dto.AiModelDto;
import com.moyz.adi.common.dto.AiModelSearchReq;
import com.moyz.adi.common.entity.AiModel;
import com.moyz.adi.common.enums.ErrorEnum;
import com.moyz.adi.common.exception.BaseException;
import com.moyz.adi.common.mapper.AiModelMapper;
import com.moyz.adi.common.util.MPPageUtil;
import dev.langchain4j.agent.tool.P;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import static com.moyz.adi.common.util.LocalCache.MODEL_ID_TO_OBJ;
@ -68,10 +65,16 @@ public class AiModelService extends ServiceImpl<AiModelMapper, AiModel> {
return existModel;
}
public Page<AiModelDto> page(String platform, Integer currentPage, Integer pageSize) {
public Page<AiModelDto> page(AiModelSearchReq aiModelSearchReq, Integer currentPage, Integer pageSize) {
LambdaQueryWrapper<AiModel> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(platform)) {
lambdaQueryWrapper.eq(AiModel::getPlatform, platform);
if (StringUtils.isNotBlank(aiModelSearchReq.getPlatform())) {
lambdaQueryWrapper.eq(AiModel::getPlatform, aiModelSearchReq.getPlatform());
}
if (StringUtils.isNotBlank(aiModelSearchReq.getType())) {
lambdaQueryWrapper.eq(AiModel::getType, aiModelSearchReq.getType());
}
if (null != aiModelSearchReq.getIsEnable()) {
lambdaQueryWrapper.eq(AiModel::getIsEnable, aiModelSearchReq.getIsEnable());
}
lambdaQueryWrapper.eq(AiModel::getIsDeleted, false);
lambdaQueryWrapper.orderByDesc(AiModel::getUpdateTime);
@ -101,6 +104,32 @@ public class AiModelService extends ServiceImpl<AiModelMapper, AiModel> {
return MPPageUtil.convertToList(aiModels, AiModelDto.class);
}
public AiModelDto addOne(AiModelDto aiModelDto) {
Long count = ChainWrappers.lambdaQueryChain(baseMapper)
.eq(AiModel::getName, aiModelDto.getName())
.eq(AiModel::getPlatform, aiModelDto.getPlatform())
.eq(AiModel::getIsDeleted, false)
.count();
if (count > 0) {
throw new BaseException(ErrorEnum.A_MODEL_ALREADY_EXIST);
}
AiModel aiModel = new AiModel();
BeanUtils.copyProperties(aiModelDto, aiModel);
baseMapper.insert(aiModel);
AiModelDto result = new AiModelDto();
BeanUtils.copyProperties(aiModel, result);
return result;
}
public void edit(AiModelDto aiModelDto) {
getByIdOrThrow(aiModelDto.getId());
AiModel aiModel = new AiModel();
BeanUtils.copyProperties(aiModelDto, aiModel, "createTime", "updateTime");
baseMapper.updateById(aiModel);
}
public void softDelete(Long id) {
AiModel existModel = getByIdOrThrow(id);

View File

@ -84,6 +84,19 @@ public class KnowledgeBaseService extends ServiceImpl<KnowledgeBaseMapper, Knowl
@Resource
private UserDayCostService userDayCostService;
public boolean updateKb(KbEditReq kbEditReq) {
KnowledgeBase existKb = getOrThrow(kbEditReq.getUuid());
KnowledgeBase knowledgeBase = new KnowledgeBase();
knowledgeBase.setTitle(kbEditReq.getTitle());
knowledgeBase.setRemark(kbEditReq.getRemark());
if (null != kbEditReq.getIsPublic()) {
knowledgeBase.setIsPublic(kbEditReq.getIsPublic());
}
knowledgeBase.setId(existKb.getId());
baseMapper.updateById(knowledgeBase);
return true;
}
public KnowledgeBase saveOrUpdate(KbEditReq kbEditReq) {
String uuid = kbEditReq.getUuid();
KnowledgeBase knowledgeBase = new KnowledgeBase();

View File

@ -91,8 +91,9 @@ public class SysConfigService extends ServiceImpl<SysConfigMapper, SysConfig> {
public Page<SysConfig> search(String keyword, Integer currentPage, Integer pageSize) {
LambdaQueryWrapper<SysConfig> wrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotBlank(keyword)) {
wrapper.eq(SysConfig::getName, keyword);
wrapper.like(SysConfig::getName, keyword);
}
wrapper.eq(SysConfig::getIsDeleted, false);
return baseMapper.selectPage(new Page<>(currentPage, pageSize), wrapper);
}

View File

@ -201,6 +201,10 @@ public class UserService extends ServiceImpl<UserMapper, User> {
User editUser = new User();
editUser.setId(user.getId());
BeanUtils.copyProperties(userEditReq, editUser);
if (StringUtils.isNotBlank(userEditReq.getPassword())) {
String hashed = BCrypt.hashpw(userEditReq.getPassword(), BCrypt.gensalt());
editUser.setPassword(hashed);
}
baseMapper.updateById(editUser);
}

View File

@ -0,0 +1,14 @@
package com.moyz.adi.common.util;
import com.moyz.adi.common.cosntant.AdiConstant;
import org.apache.commons.lang3.StringUtils;
public class AiModelUtil {
public static boolean checkModelType(String modelType) {
return StringUtils.equalsAny(modelType, AdiConstant.ModelType.TEXT, AdiConstant.ModelType.IMAGE, AdiConstant.ModelType.EMBEDDING, AdiConstant.ModelType.RERANK);
}
public static boolean checkModelPlatform(String platform) {
return StringUtils.equalsAny(platform, AdiConstant.ModelPlatform.OPENAI, AdiConstant.ModelPlatform.DASHSCOPE, AdiConstant.ModelPlatform.QIANFAN, AdiConstant.ModelPlatform.OLLAMA);
}
}

View File

@ -49,16 +49,17 @@ COMMENT ON COLUMN public.adi_ai_image.is_deleted IS 'Flag indicating whether the
CREATE TABLE public.adi_ai_model
(
id bigserial primary key,
name varchar(45) default '' not null,
type varchar(45) default 'llm' not null,
remark varchar(1000) default '',
platform varchar(45) default '' not null,
max_tokens int default 0 not null,
is_enable boolean default false NOT NULL,
create_time timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
update_time timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_deleted boolean DEFAULT false NOT NULL
id bigserial primary key,
name varchar(45) default '' not null,
type varchar(45) default 'llm' not null,
remark varchar(1000) default '',
platform varchar(45) default '' not null,
context_window int default 0 not null,
max_tokens int default 0 not null,
is_enable boolean default false NOT NULL,
create_time timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
update_time timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
is_deleted boolean DEFAULT false NOT NULL
);
COMMENT ON TABLE public.adi_ai_model IS 'ai模型';
@ -66,13 +67,14 @@ COMMENT ON COLUMN public.adi_ai_model.type IS 'The type of the AI model,eg: text
COMMENT ON COLUMN public.adi_ai_model.name IS 'The name of the AI model';
COMMENT ON COLUMN public.adi_ai_model.remark IS 'Additional remarks about the AI model';
COMMENT ON COLUMN public.adi_ai_model.platform IS 'eg: openai,dashscope,qianfan,ollama';
COMMENT ON COLUMN public.adi_ai_model.context_window IS 'LLM context window';
COMMENT ON COLUMN public.adi_ai_model.max_tokens IS 'The maximum number of tokens that can be generated';
COMMENT ON COLUMN public.adi_ai_model.is_enable IS '1: Normal usage, 0: Not available';
COMMENT ON COLUMN public.adi_ai_model.create_time IS 'Timestamp of record creation';
COMMENT ON COLUMN public.adi_ai_model.update_time IS 'Timestamp of record last update, automatically updated on each update';
INSERT INTO adi_ai_model (name, type, platform, max_tokens, is_enable)
VALUES ('gpt-3.5-turbo', 'text', 'openai', 2048, false);
INSERT INTO adi_ai_model (name, type, platform, context_window, max_tokens, is_enable)
VALUES ('gpt-3.5-turbo', 'text', 'openai', 16385, 4096, false);
INSERT INTO adi_ai_model (name, type, platform, is_enable)
VALUES ('dall-e-2', 'image', 'openai', false);
INSERT INTO adi_ai_model (name, type, platform, is_enable)