refactor(service): 重构服务模块结构并优化模型配置
This commit is contained in:
254
service/model/model_service.go
Normal file
254
service/model/model_service.go
Normal file
@@ -0,0 +1,254 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"model-gateway/common/util"
|
||||
"model-gateway/consts/public"
|
||||
"model-gateway/dao"
|
||||
"model-gateway/model/dto"
|
||||
"model-gateway/model/entity"
|
||||
"model-gateway/service/gateway"
|
||||
|
||||
"gitea.com/red-future/common/beans"
|
||||
"gitea.com/red-future/common/db/gfdb"
|
||||
"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"
|
||||
)
|
||||
|
||||
var Model = &modelService{}
|
||||
|
||||
type modelService struct{}
|
||||
|
||||
// Create 创建模型
|
||||
func (s *modelService) Create(ctx context.Context, req *dto.CreateModelReq) (*dto.CreateModelRes, error) {
|
||||
// 1)如果设为会话模型,先把该用户旧会话模型取消
|
||||
if !g.IsEmpty(req.IsChatModel) && *req.IsChatModel == 1 {
|
||||
if err := s.clearUserChatModel(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// 2)判断是否超管,决定 isOwner
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
if isAdmin, _ := gateway.IsSuperAdmin(ctx); isAdmin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
}
|
||||
|
||||
// 3)入库
|
||||
id, err := dao.Model.Insert(ctx, util.ConvertTo[entity.AsynchModel](req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.CreateModelRes{ID: id}, nil
|
||||
}
|
||||
|
||||
// Update 更新模型配置
|
||||
func (s *modelService) Update(ctx context.Context, req *dto.UpdateModelReq) error {
|
||||
// 1)会话模型唯一性校验
|
||||
if req.IsChatModel != nil && *req.IsChatModel == 1 {
|
||||
if err := s.checkChatModelUnique(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// 2)超管创建/普通用户更新
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
if isAdmin, _ := gateway.IsSuperAdmin(ctx); isAdmin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
_, err := dao.Model.Update(ctx, util.ConvertTo[entity.AsynchModel](req))
|
||||
return err
|
||||
}
|
||||
// 3)跨租户判断:超管的模型不允许直接修改,走插入新记录
|
||||
model, err := dao.Model.GetByAcrossTenant(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: req.ID},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if model.TenantId == 1 {
|
||||
_, err = dao.Model.Insert(ctx, util.ConvertTo[entity.AsynchModel](req))
|
||||
return err
|
||||
}
|
||||
_, err = dao.Model.Update(ctx, util.ConvertTo[entity.AsynchModel](req))
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete 删除模型
|
||||
func (s *modelService) Delete(ctx context.Context, req *dto.DeleteModelReq) error {
|
||||
_, err := dao.Model.Delete(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: req.ID},
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Get 获取模型详情
|
||||
func (s *modelService) Get(ctx context.Context, req *dto.GetModelReq) (*dto.GetModelRes, error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if g.IsEmpty(req.ID) {
|
||||
req.Creator = user.UserName
|
||||
}
|
||||
modelReq := new(entity.AsynchModel)
|
||||
err = gconv.Struct(req, modelReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
model, err := dao.Model.Get(ctx, modelReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.GetModelRes{
|
||||
Model: model,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// List 获取模型列表
|
||||
func (s *modelService) List(ctx context.Context, req *dto.ListModelReq) (*dto.ListModelRes, error) {
|
||||
// 1)判断超管
|
||||
req.IsOwner = gconv.PtrInt(1)
|
||||
if isAdmin, _ := gateway.IsSuperAdmin(ctx); isAdmin {
|
||||
req.IsOwner = gconv.PtrInt(0)
|
||||
}
|
||||
|
||||
// 2)获取当前用户
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Creator = user.UserName
|
||||
|
||||
// 3)查询
|
||||
models, total, err := dao.Model.GetByCreatorAndPlatform(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &dto.ListModelRes{List: models, Total: total}, nil
|
||||
}
|
||||
|
||||
// UpdateChatModel 设置会话模型
|
||||
func (s *modelService) UpdateChatModel(ctx context.Context, req *dto.UpdateChatModelReq) error {
|
||||
// 1)校验新模型存在
|
||||
newModel, err := dao.Model.GetByAcrossTenant(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: req.Id},
|
||||
})
|
||||
if err != nil || newModel == nil {
|
||||
return errors.New("新会话模型不存在")
|
||||
}
|
||||
|
||||
// 2)获取当前用户的会话模型
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
currentModel, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Creator: user.UserName},
|
||||
IsChatModel: new(1),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3)事务:取消旧的 + 设置新的
|
||||
return gfdb.DB(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||
if !g.IsEmpty(currentModel) {
|
||||
if currentModel.ModelType != public.ModelTypeInference {
|
||||
return errors.New("当前模型为非推理模型,不能设置为会话模型")
|
||||
}
|
||||
if currentModel.Id != req.Id {
|
||||
_, err = dao.Model.Update(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: currentModel.Id},
|
||||
IsChatModel: gconv.PtrInt(0),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = dao.Model.Update(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: req.Id},
|
||||
IsChatModel: gconv.PtrInt(1),
|
||||
})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// GetIsChatModel 获取当前用户会话模型
|
||||
func (s *modelService) GetIsChatModel(ctx context.Context) (*dto.GetIsChatModelRes, error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
model, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Creator: user.UserName},
|
||||
IsChatModel: new(1),
|
||||
})
|
||||
if err != nil || model == nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto.GetIsChatModelRes{Model: model}, nil
|
||||
}
|
||||
|
||||
// ==================== 辅助方法 ====================
|
||||
|
||||
// clearUserChatModel 清除当前用户旧会话模型
|
||||
func (s *modelService) clearUserChatModel(ctx context.Context) error {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
model, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Creator: user.UserName},
|
||||
IsChatModel: new(1),
|
||||
})
|
||||
if err != nil || model == nil {
|
||||
return nil
|
||||
}
|
||||
_, err = dao.Model.Update(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Id: model.Id},
|
||||
IsChatModel: gconv.PtrInt(0),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// checkChatModelUnique 校验用户是否已有会话模型
|
||||
func (s *modelService) checkChatModelUnique(ctx context.Context) error {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
model, err := dao.Model.Get(ctx, &entity.AsynchModel{
|
||||
SQLBaseDO: beans.SQLBaseDO{Creator: user.UserName},
|
||||
IsChatModel: new(1),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if model != nil {
|
||||
return errors.New("用户已存在会话模型")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetModelTypesFromConfig 从配置文件读取模型类型
|
||||
func GetModelTypesFromConfig() (res *dto.TypeItem, err error) {
|
||||
// 返回副本,避免外部修改
|
||||
types := make(map[int]string, len(public.ModelTypeName))
|
||||
for k, v := range public.ModelTypeName {
|
||||
types[k] = v
|
||||
}
|
||||
return &dto.TypeItem{
|
||||
Type: types,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetOperatorList 获取运营商列表
|
||||
func GetOperatorList() (res *dto.ListOperatorRes, err error) {
|
||||
return &dto.ListOperatorRes{
|
||||
List: public.OperatorList,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user