update: 更新配置文件中的服务地址,修改模型管理相关代码,调整数据结构和逻辑,优化模型列表查询和会话模型设置,更新数据库表结构和索引,修改模块名称和依赖版本
This commit is contained in:
@@ -3,13 +3,15 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"model-asynch/dao"
|
||||
"model-asynch/model/dto"
|
||||
"model-asynch/model/entity"
|
||||
"model-gateway/dao"
|
||||
"model-gateway/model/dto"
|
||||
"model-gateway/model/entity"
|
||||
|
||||
"gitea.com/red-future/common/beans"
|
||||
"gitea.com/red-future/common/db/gfdb"
|
||||
"gitea.com/red-future/common/http"
|
||||
"gitea.com/red-future/common/utils"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@@ -18,32 +20,45 @@ var Model = &modelService{}
|
||||
|
||||
type modelService struct{}
|
||||
|
||||
func (s *modelService) Create(ctx context.Context, req *dto.CreateModelReq) (res *dto.CreateModelRes, err error) {
|
||||
m := &entity.AsynchModel{
|
||||
ModelName: req.ModelName,
|
||||
ModelsType: req.ModelsType,
|
||||
BaseURL: req.BaseURL,
|
||||
HttpMethod: req.HttpMethod,
|
||||
HeadMsg: req.HeadMsg,
|
||||
IsPrivate: req.IsPrivate,
|
||||
Enabled: req.Enabled,
|
||||
IsChatModel: req.IsChatModel,
|
||||
ApiKey: req.ApiKey,
|
||||
Form: req.Form,
|
||||
RequestMapping: req.RequestMapping,
|
||||
ResponseMapping: req.ResponseMapping,
|
||||
ResponseBody: req.ResponseBody,
|
||||
TokenMapping: req.TokenMapping,
|
||||
MaxConcurrency: req.MaxConcurrency,
|
||||
QueueLimit: req.QueueLimit,
|
||||
TimeoutSeconds: req.TimeoutSeconds,
|
||||
ExpectedSeconds: req.ExpectedSeconds,
|
||||
RetryTimes: req.RetryTimes,
|
||||
RetryQueueMaxSeconds: req.RetryQueueMaxSeconds,
|
||||
AutoCleanSeconds: req.AutoCleanSeconds,
|
||||
Remark: req.Remark,
|
||||
// IsSuperAdmin 调用admin-go服务检查是否是超级管理员
|
||||
func (s *modelService) IsSuperAdmin(ctx context.Context) (res bool, err error) {
|
||||
headers := forwardHeaders(ctx)
|
||||
var r = make(map[string]bool)
|
||||
if err = http.Get(ctx, "admin-go/api/v1/system/user/checkIsSuperAdmin", headers, &r); err != nil {
|
||||
return false, err
|
||||
}
|
||||
id, err := dao.Model.Insert(ctx, m)
|
||||
return r["isSuperAdmin"], err
|
||||
}
|
||||
|
||||
func (s *modelService) Create(ctx context.Context, req *dto.CreateModelReq) (res *dto.CreateModelRes, err error) {
|
||||
// 获取当前会话模型
|
||||
if !g.IsEmpty(req.IsChatModel) && *req.IsChatModel == 1 {
|
||||
var model *entity.AsynchModel
|
||||
model, err = dao.Model.GetByIsChatModel(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 如果有会话模型,那就改变为 0
|
||||
if model != nil {
|
||||
_, err = dao.Model.Update(ctx, &dto.UpdateModelReq{
|
||||
ID: model.Id,
|
||||
IsChatModel: gconv.PtrInt(0),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
admin, err := s.IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if admin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
}
|
||||
id, err := dao.Model.Insert(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -52,23 +67,55 @@ func (s *modelService) Create(ctx context.Context, req *dto.CreateModelReq) (res
|
||||
|
||||
func (s *modelService) Update(ctx context.Context, req *dto.UpdateModelReq) error {
|
||||
//根据当前 isChatModel 来判断是否更新模型
|
||||
if req.IsChatModel == 1 {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if req.IsChatModel == gconv.PtrInt(1) {
|
||||
//判断当前用户是否有会话模型
|
||||
model, err := dao.Model.GetByIsChatModel(ctx, user.UserName)
|
||||
model, err := dao.Model.GetByIsChatModel(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if model != nil {
|
||||
return errors.New("用户已存在会话模型,不能创建新的会话模型")
|
||||
return errors.New("用户已存在会话模型,不能创建")
|
||||
}
|
||||
_, err = dao.Model.Update(ctx, req)
|
||||
}
|
||||
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
admin, err := s.IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := dao.Model.Update(ctx, req)
|
||||
if admin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
_, err = dao.Model.Update(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var user *beans.User
|
||||
user, err = utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 判断当前传过来的模型id的模型是否是超级管理员的。如果是超管的进行创建,否则更新
|
||||
var count int
|
||||
count, err = dao.Model.Count(ctx, &dto.GetModelReq{
|
||||
ID: req.ID,
|
||||
Creator: user.UserName,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
insertDto := new(dto.CreateModelReq)
|
||||
err = gconv.Struct(req, insertDto)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = dao.Model.Insert(ctx, insertDto)
|
||||
return err
|
||||
}
|
||||
_, err = dao.Model.Update(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -89,27 +136,29 @@ func (s *modelService) Get(ctx context.Context, id int64) (*entity.AsynchModel,
|
||||
return model, nil
|
||||
}
|
||||
|
||||
func (s *modelService) List(ctx context.Context, pageNum, pageSize int, req *dto.ListModelReq) (list []*entity.AsynchModel, total int64, err error) {
|
||||
isSuperAdmin, err := IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
func (s *modelService) List(ctx context.Context, req *dto.ListModelReq) (list []*entity.AsynchModel, total int, err error) {
|
||||
var models []*entity.AsynchModel
|
||||
var count int64
|
||||
|
||||
if isSuperAdmin {
|
||||
models, count, err = dao.Model.List(ctx, pageNum, pageSize, req.ModelName, req.ModelType, req.IsPrivate)
|
||||
} else {
|
||||
models, count, err = s.getModelsWithDedup(ctx, user.UserName, pageNum, pageSize, req.ModelName, req.ModelType, req.IsPrivate)
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
admin, err := s.IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if admin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
}
|
||||
|
||||
var user *beans.User
|
||||
user, err = utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
req.Creator = user.UserName
|
||||
|
||||
models, total, err = dao.Model.GetByCreatorAndPlatform(ctx, req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理列表中每条记录的 JSONB 字段
|
||||
for _, m := range models {
|
||||
@@ -118,61 +167,7 @@ func (s *modelService) List(ctx context.Context, pageNum, pageSize int, req *dto
|
||||
m.ResponseMapping = ParseJSONField(m.ResponseMapping)
|
||||
m.ResponseBody = ParseJSONField(m.ResponseBody)
|
||||
}
|
||||
return models, count, nil
|
||||
}
|
||||
|
||||
// getModelsWithDedup 获取普通用户的模型列表并去重
|
||||
func (s *modelService) getModelsWithDedup(ctx context.Context, creator string, pageNum, pageSize int, modelNameLike string, modelType int, isPrivate int) (list []*entity.AsynchModel, total int64, err error) {
|
||||
// 1. 查全量数据(不分页,便于去重)
|
||||
allModels, err := dao.Model.GetByCreatorAndPlatform(ctx, creator, modelNameLike, modelType, isPrivate)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 2. 按 modelName 去重,保留当前用户的
|
||||
modelMap := make(map[string]*entity.AsynchModel)
|
||||
for _, m := range allModels {
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
name := m.ModelName
|
||||
|
||||
_, ok := modelMap[name]
|
||||
if !ok {
|
||||
// 没有冲突,直接放进去
|
||||
modelMap[name] = m
|
||||
} else {
|
||||
// 有冲突,保留当前用户创建的
|
||||
if m.Creator == creator {
|
||||
modelMap[name] = m
|
||||
}
|
||||
// 如果现有的就是当前用户的,不做任何替换
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 转回切片并排序
|
||||
deduped := make([]*entity.AsynchModel, 0, len(modelMap))
|
||||
for _, m := range modelMap {
|
||||
deduped = append(deduped, m)
|
||||
}
|
||||
sort.Slice(deduped, func(i, j int) bool {
|
||||
return deduped[i].CreatedAt.After(deduped[j].CreatedAt)
|
||||
})
|
||||
|
||||
// 4. 手动分页
|
||||
total = int64(len(deduped))
|
||||
if pageNum > 0 && pageSize > 0 {
|
||||
start := (pageNum - 1) * pageSize
|
||||
if start >= len(deduped) {
|
||||
return []*entity.AsynchModel{}, total, nil
|
||||
}
|
||||
end := start + pageSize
|
||||
if end > len(deduped) {
|
||||
end = len(deduped)
|
||||
}
|
||||
deduped = deduped[start:end]
|
||||
}
|
||||
return deduped, total, nil
|
||||
return models, total, nil
|
||||
}
|
||||
|
||||
// GetModelTypesFromConfig 从配置文件读取模型类型
|
||||
@@ -202,11 +197,6 @@ func GetModelTypesFromConfig(ctx context.Context) map[int]string {
|
||||
}
|
||||
|
||||
func (s *modelService) UpdateChatModel(ctx context.Context, req *dto.UpdateChatModelReq) error {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 校验新会话模型是否存在
|
||||
newModel, err := dao.Model.Get(ctx, req.Id)
|
||||
if err != nil {
|
||||
@@ -217,48 +207,40 @@ func (s *modelService) UpdateChatModel(ctx context.Context, req *dto.UpdateChatM
|
||||
}
|
||||
|
||||
// 获取当前用户会话模型
|
||||
currentModel, err := dao.Model.GetByIsChatModel(ctx, user.UserName)
|
||||
currentModel, err := dao.Model.GetByIsChatModel(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if currentModel.ModelsType != 1 {
|
||||
return errors.New("当前模型为非推理模型,不能设置为会话模型")
|
||||
}
|
||||
err = gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
if !g.IsEmpty(currentModel) {
|
||||
if currentModel.ModelType != 1 {
|
||||
return errors.New("当前模型为非推理模型,不能设置为会话模型")
|
||||
}
|
||||
|
||||
// 如果点击的就是当前会话模型(已经是1),取消它(设为0)
|
||||
if currentModel != nil && currentModel.Id == req.Id {
|
||||
_, err = dao.Model.UpdateByID(ctx, &dto.UpdateModelReq{
|
||||
// 如果点击的就是当前会话模型(已经是1),取消它(设为0)
|
||||
if currentModel.Id != req.Id {
|
||||
_, err = dao.Model.Update(ctx, &dto.UpdateModelReq{
|
||||
ID: currentModel.Id,
|
||||
IsChatModel: gconv.PtrInt(0),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置当前为会话模型(设为1)
|
||||
_, err = dao.Model.Update(ctx, &dto.UpdateModelReq{
|
||||
ID: req.Id,
|
||||
IsChatModel: 0,
|
||||
IsChatModel: gconv.PtrInt(1),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// 如果之前有会话模型,取消它(设为0)
|
||||
if currentModel != nil {
|
||||
_, err = dao.Model.UpdateByID(ctx, &dto.UpdateModelReq{
|
||||
ID: currentModel.Id,
|
||||
IsChatModel: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 设置当前为会话模型(设为1)
|
||||
_, err = dao.Model.UpdateByID(ctx, &dto.UpdateModelReq{
|
||||
ID: req.Id,
|
||||
IsChatModel: 1,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *modelService) GetIsChatModel(ctx context.Context) (*entity.AsynchModel, error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
model, err := dao.Model.GetByIsChatModel(ctx, user.UserName)
|
||||
model, err := dao.Model.GetByIsChatModel(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user