Files
model-asynch/service/model_service.go
WangLiZhao f6c70a451e feat: 新增操作日志、任务分页查询与模型失败重试优化
- 新增操作日志表(asynch_op_log)及对应DAO,记录任务创建等操作的审计信息
- 新增任务分页查询接口(ListTask)及对应DTO、Service和DAO方法
- 优化模型调用失败重试逻辑:支持配置重试排队策略(插队到队首或队尾)
- 新增临时文件存储机制,当模型调用成功但OSS上传失败时,下次仅重试OSS上传
- 模型配置新增retry_queue_max_seconds字段,控制失败重试排队策略
- 更新数据库表结构(asynch_models、asynch_task、新增asynch_op_log)及同步更新SQL
- 配置文件调整:超时单位改为秒,更新服务地址和轮询间隔
- 修复模型列表查询支持按名称模糊搜索
2026-04-25 10:42:21 +08:00

114 lines
3.0 KiB
Go

package service
import (
"context"
"errors"
"model-asynch/dao"
"model-asynch/model/dto"
"model-asynch/model/entity"
)
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,
BaseURL: req.BaseURL,
Route: req.Route,
HttpMethod: req.HttpMethod,
APIKey: req.APIKey,
Enabled: req.Enabled,
MaxConcurrency: req.MaxConcurrency,
QueueLimit: req.QueueLimit,
TimeoutSeconds: req.TimeoutSeconds,
RetryTimes: req.RetryTimes,
RetryQueueMaxSecs: req.RetryQueueMaxSeconds,
AutoCleanSeconds: req.AutoCleanSeconds,
Remark: req.Remark,
}
if m.HttpMethod == "" {
m.HttpMethod = "POST"
}
if m.Enabled == 0 {
m.Enabled = 1
}
if m.MaxConcurrency <= 0 {
m.MaxConcurrency = 10
}
if m.QueueLimit <= 0 {
m.QueueLimit = 1000
}
if m.TimeoutSeconds <= 0 {
m.TimeoutSeconds = 60
}
if m.AutoCleanSeconds <= 0 {
m.AutoCleanSeconds = 86400
}
id, err := dao.Model.Insert(ctx, m)
if err != nil {
return nil, err
}
return &dto.CreateModelRes{ID: id}, nil
}
func (s *modelService) Update(ctx context.Context, req *dto.UpdateModelReq) error {
data := map[string]any{}
if req.BaseURL != "" {
data[entity.AsynchModelCol.BaseURL] = req.BaseURL
}
if req.Route != "" {
data[entity.AsynchModelCol.Route] = req.Route
}
if req.HttpMethod != nil && *req.HttpMethod != "" {
data[entity.AsynchModelCol.HttpMethod] = *req.HttpMethod
}
if req.APIKey != nil {
data[entity.AsynchModelCol.APIKey] = *req.APIKey
}
if req.Enabled != nil {
data[entity.AsynchModelCol.Enabled] = *req.Enabled
}
if req.MaxConcurrency != nil {
data[entity.AsynchModelCol.MaxConcurrency] = *req.MaxConcurrency
}
if req.QueueLimit != nil {
data[entity.AsynchModelCol.QueueLimit] = *req.QueueLimit
}
if req.TimeoutSeconds != nil {
data[entity.AsynchModelCol.TimeoutSeconds] = *req.TimeoutSeconds
}
if req.RetryTimes != nil {
data[entity.AsynchModelCol.RetryTimes] = *req.RetryTimes
}
if req.RetryQueueMaxSeconds != nil {
data[entity.AsynchModelCol.RetryQueueMaxSecs] = *req.RetryQueueMaxSeconds
}
if req.AutoCleanSeconds != nil {
data[entity.AsynchModelCol.AutoCleanSeconds] = *req.AutoCleanSeconds
}
if req.Remark != nil {
data[entity.AsynchModelCol.Remark] = *req.Remark
}
if len(data) == 0 {
return errors.New("无可更新字段")
}
_, err := dao.Model.UpdateByID(ctx, req.ID, data)
return err
}
func (s *modelService) Delete(ctx context.Context, id int64) error {
_, err := dao.Model.DeleteByID(ctx, id)
return err
}
func (s *modelService) Get(ctx context.Context, id int64) (*entity.AsynchModel, error) {
return dao.Model.GetByID(ctx, id)
}
func (s *modelService) List(ctx context.Context, pageNum, pageSize int, modelNameLike string) (list []*entity.AsynchModel, total int64, err error) {
return dao.Model.List(ctx, pageNum, pageSize, modelNameLike)
}