From 1c0f1a7707f89c59489c30bb42a06c97a198051c Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Thu, 13 Aug 2026 16:49:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=9A=E8=AF=9D=20Get=20=E6=8C=89=20?= =?UTF-8?q?exec=5Fchat/exec=5Fworkflow=20=E6=B7=B7=E6=8E=92=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/session/session_controller.go | 22 +- workflow/dao/session/exec_chat_dao.go | 64 ++++++ workflow/dao/session/exec_workflow_dao.go | 74 +++++++ .../dao/session/exec_workflow_result_dao.go | 64 ++++++ workflow/dao/session/session_dao.go | 188 +----------------- workflow/service/session/session_service.go | 165 +++++++-------- 6 files changed, 285 insertions(+), 292 deletions(-) create mode 100644 workflow/dao/session/exec_chat_dao.go create mode 100644 workflow/dao/session/exec_workflow_dao.go create mode 100644 workflow/dao/session/exec_workflow_result_dao.go diff --git a/workflow/controller/session/session_controller.go b/workflow/controller/session/session_controller.go index a799218..15ee212 100644 --- a/workflow/controller/session/session_controller.go +++ b/workflow/controller/session/session_controller.go @@ -3,17 +3,18 @@ package session import ( "context" - "gitea.redpowerfuture.com/red-future/common/beans" sessionDto "ai-agent/workflow/model/dto/session" sessionService "ai-agent/workflow/service/session" + + "gitea.redpowerfuture.com/red-future/common/beans" ) type session struct{} var Session = new(session) -func (c *session) Create(ctx context.Context, req *sessionDto.CreateSessionReq) (res *sessionDto.CreateSessionRes, err error) { - return sessionService.SessionService.Create(ctx, req) +func (c *session) Get(ctx context.Context, req *sessionDto.GetSessionInfoReq) (res *sessionDto.GetSessionInfoRes, err error) { + return sessionService.SessionService.Get(ctx, req) } func (c *session) List(ctx context.Context, req *sessionDto.ListSessionReq) (res *sessionDto.ListSessionRes, err error) { @@ -26,18 +27,3 @@ func (c *session) Delete(ctx context.Context, req *sessionDto.DeleteSessionReq) } return &beans.ResponseEmpty{}, nil } - -func (c *session) Results(ctx context.Context, req *sessionDto.ListSessionResultsReq) (res *sessionDto.ListSessionResultsRes, err error) { - return sessionService.SessionService.ListSessionResults(ctx, req) -} - -func (c *session) ResultDelete(ctx context.Context, req *sessionDto.DeleteSessionResultReq) (res *beans.ResponseEmpty, err error) { - if err = sessionService.SessionService.DeleteResult(ctx, req); err != nil { - return - } - return &beans.ResponseEmpty{}, nil -} - -func (c *session) WorkflowResults(ctx context.Context, req *sessionDto.ListWorkflowResultsReq) (res *sessionDto.ListWorkflowResultsRes, err error) { - return sessionService.SessionService.ListWorkflowResults(ctx, req) -} \ No newline at end of file diff --git a/workflow/dao/session/exec_chat_dao.go b/workflow/dao/session/exec_chat_dao.go new file mode 100644 index 0000000..7009443 --- /dev/null +++ b/workflow/dao/session/exec_chat_dao.go @@ -0,0 +1,64 @@ +package session + +import ( + "ai-agent/workflow/consts/public" + sessionDto "ai-agent/workflow/model/dto/session" + "ai-agent/workflow/model/entity" + "context" + + "gitea.redpowerfuture.com/red-future/common/beans" + "gitea.redpowerfuture.com/red-future/common/db/gfdb" + "github.com/gogf/gf/v2/util/gconv" +) + +var ExecChatDao = &execChatDao{} + +type execChatDao struct{} + +func (d *execChatDao) Insert(ctx context.Context, req *sessionDto.CreateExecChatReq) (id int64, err error) { + var s = new(entity.ExecChat) + if err = gconv.Struct(req, &s); err != nil { + return + } + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecChat).Insert(s) + if err != nil { + return + } + return r.LastInsertId() +} + +func (d *execChatDao) Delete(ctx context.Context, req *sessionDto.DeleteExecChatReq) (rows int64, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecChat).Where(entity.ExecChatCol.Id, req.Id).Delete() + if err != nil { + return + } + return r.RowsAffected() +} + +func (d *execChatDao) List(ctx context.Context, creator string, page *beans.Page) (res []*entity.ExecChat, total int, err error) { + m := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecChat). + Where(entity.ExecChatCol.Creator, creator) + m.OrderDesc(entity.ExecChatCol.CreatedAt) + if page != nil { + m.Page(int(page.PageNum), int(page.PageSize)) + } + r, total, err := m.AllAndCount(false) + if err != nil { + return + } + err = r.Structs(&res) + return +} + +// ListBySession 查询会话下普通对话执行记录(按创建时间倒序) +func (d *execChatDao) ListBySession(ctx context.Context, sessionId int64) (res []*entity.ExecChat, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecChat). + Where(entity.ExecChatCol.SessionId, sessionId). + OrderDesc(entity.ExecChatCol.CreatedAt). + All() + if err != nil { + return + } + err = r.Structs(&res) + return +} diff --git a/workflow/dao/session/exec_workflow_dao.go b/workflow/dao/session/exec_workflow_dao.go new file mode 100644 index 0000000..f11616b --- /dev/null +++ b/workflow/dao/session/exec_workflow_dao.go @@ -0,0 +1,74 @@ +package session + +import ( + "ai-agent/workflow/consts/public" + sessionDto "ai-agent/workflow/model/dto/session" + "ai-agent/workflow/model/entity" + "context" + + "gitea.redpowerfuture.com/red-future/common/beans" + "gitea.redpowerfuture.com/red-future/common/db/gfdb" + "github.com/gogf/gf/v2/util/gconv" +) + +var ExecWorkflowDao = &execWorkflowDao{} + +type execWorkflowDao struct{} + +func (d *execWorkflowDao) Insert(ctx context.Context, req *sessionDto.CreateExecChatReq) (id int64, err error) { + var s = new(entity.ExecWorkflow) + if err = gconv.Struct(req, &s); err != nil { + return + } + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflow).Insert(s) + if err != nil { + return + } + return r.LastInsertId() +} + +func (d *execWorkflowDao) Delete(ctx context.Context, req *sessionDto.DeleteWorkflowReq) (rows int64, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflow).Where(entity.ExecWorkflowCol.Id, req.Id).Delete() + if err != nil { + return + } + return r.RowsAffected() +} + +func (d *execWorkflowDao) Update(ctx context.Context, req *sessionDto.UpdateWorkflowReq) (rows int64, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflow).OmitEmpty().Data(&req).Where(entity.ExecWorkflowCol.Id, req.Id).Update() + if err != nil { + return + } + return r.RowsAffected() +} + +func (d *execWorkflowDao) List(ctx context.Context, creator string, page *beans.Page) (res []*entity.ExecWorkflow, total int, err error) { + m := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflow). + Where(entity.ExecWorkflowCol.Creator, creator) + m.OrderDesc(entity.ExecWorkflowCol.CreatedAt) + if page != nil { + m.Page(int(page.PageNum), int(page.PageSize)) + } + r, total, err := m.AllAndCount(false) + if err != nil { + return + } + err = r.Structs(&res) + return +} + +// ListBySession 查询会话下工作流执行记录(按创建时间倒序) +func (d *execWorkflowDao) ListBySession(ctx context.Context, sessionId int64) (res []*entity.ExecWorkflow, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflow). + Where(entity.ExecWorkflowCol.SessionId, sessionId). + OrderDesc(entity.ExecWorkflowCol.CreatedAt). + All() + if err != nil { + return + } + err = r.Structs(&res) + return +} + + diff --git a/workflow/dao/session/exec_workflow_result_dao.go b/workflow/dao/session/exec_workflow_result_dao.go new file mode 100644 index 0000000..f996621 --- /dev/null +++ b/workflow/dao/session/exec_workflow_result_dao.go @@ -0,0 +1,64 @@ +package session + +import ( + "ai-agent/workflow/consts/public" + sessionDto "ai-agent/workflow/model/dto/session" + "ai-agent/workflow/model/entity" + "context" + + "gitea.redpowerfuture.com/red-future/common/beans" + "gitea.redpowerfuture.com/red-future/common/db/gfdb" + "github.com/gogf/gf/v2/util/gconv" +) + +var ExecWorkflowResultDao = &execWorkflowResultDao{} + +type execWorkflowResultDao struct{} + +func (d *execWorkflowResultDao) Insert(ctx context.Context, req *sessionDto.CreateWorkflowResultReq) (id int64, err error) { + var s = new(entity.ExecWorkflowResult) + if err = gconv.Struct(req, &s); err != nil { + return + } + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflowResult).Insert(s) + if err != nil { + return + } + return r.LastInsertId() +} + +func (d *execWorkflowResultDao) Delete(ctx context.Context, req *sessionDto.DeleteWorkflowResultReq) (rows int64, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflowResult).Where(entity.ExecWorkflowResultCol.Id, req.Id).Delete() + if err != nil { + return + } + return r.RowsAffected() +} + +func (d *execWorkflowResultDao) List(ctx context.Context, creator string, page *beans.Page) (res []*entity.ExecWorkflowResult, total int, err error) { + m := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflowResult). + Where(entity.ExecWorkflowResultCol.Creator, creator) + m.OrderDesc(entity.ExecWorkflowResultCol.CreatedAt) + if page != nil { + m.Page(int(page.PageNum), int(page.PageSize)) + } + r, total, err := m.AllAndCount(false) + if err != nil { + return + } + err = r.Structs(&res) + return +} + +// ListBySession 查询会话下工作流结果(按创建时间倒序) +func (d *execWorkflowResultDao) ListBySession(ctx context.Context, sessionId int64) (res []*entity.ExecWorkflowResult, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameExecWorkflowResult). + Where(entity.ExecWorkflowResultCol.SessionId, sessionId). + OrderDesc(entity.ExecWorkflowResultCol.CreatedAt). + All() + if err != nil { + return + } + err = r.Structs(&res) + return +} diff --git a/workflow/dao/session/session_dao.go b/workflow/dao/session/session_dao.go index b8c2a91..a9da7c9 100644 --- a/workflow/dao/session/session_dao.go +++ b/workflow/dao/session/session_dao.go @@ -8,17 +8,10 @@ import ( "gitea.redpowerfuture.com/red-future/common/beans" "gitea.redpowerfuture.com/red-future/common/db/gfdb" - "github.com/gogf/gf/v2/database/gdb" - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" ) -var ( - SessionDao = &sessionDao{} - WorkflowSessionResultDao = &workflowSessionResultDao{} - ChatSessionResultDao = &chatSessionResultDao{} -) +var SessionDao = &sessionDao{} type sessionDao struct{} @@ -34,22 +27,17 @@ func (d *sessionDao) Insert(ctx context.Context, req *sessionDto.CreateSessionRe return r.LastInsertId() } -func (d *sessionDao) Get(ctx context.Context, id int64) (res *entity.Session, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameSession). - Where(entity.SessionCol.Id, id). - Where("deleted_at IS NULL"). - One() +func (d *sessionDao) Delete(ctx context.Context, req *sessionDto.DeleteSessionReq) (rows int64, err error) { + r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameSession).Where(entity.SessionCol.Id, req.Id).Delete() if err != nil { return } - err = r.Struct(&res) - return + return r.RowsAffected() } func (d *sessionDao) List(ctx context.Context, creator string, page *beans.Page) (res []*entity.Session, total int, err error) { m := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameSession). - Where(entity.SessionCol.Creator, creator). - Where("deleted_at IS NULL") + Where(entity.SessionCol.Creator, creator) m.OrderDesc(entity.SessionCol.CreatedAt) if page != nil { m.Page(int(page.PageNum), int(page.PageSize)) @@ -61,169 +49,3 @@ func (d *sessionDao) List(ctx context.Context, creator string, page *beans.Page) err = r.Structs(&res) return } - -// DeleteCascade 软删会话,并级联软删该会话下所有普通对话结果(工作流结果保留) -func (d *sessionDao) DeleteCascade(ctx context.Context, id int64) (err error) { - return gfdb.DB(ctx, public.DbNameBlackDeacon).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { - _, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameSession). - Data(g.Map{ - entity.SessionCol.DeletedAt: gtime.Now(), - entity.SessionCol.Updater: "", - }). - Where(entity.SessionCol.Id, id). - Where("deleted_at IS NULL"). - Update() - if err != nil { - return err - } - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameChatSessionResult). - Data(g.Map{ - entity.ChatSessionResultCol.DeletedAt: gtime.Now(), - entity.ChatSessionResultCol.Updater: "", - }). - Where(entity.ChatSessionResultCol.SessionId, id). - Where("deleted_at IS NULL"). - Update() - return err - }) -} - -type workflowSessionResultDao struct{} - -func (d *workflowSessionResultDao) Insert(ctx context.Context, w *entity.WorkflowSessionResult) (id int64, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult).Insert(w) - if err != nil { - return - } - return r.LastInsertId() -} - -func (d *workflowSessionResultDao) GetLatestBySessionAndFlow(ctx context.Context, sessionId, flowId int64) (res *entity.WorkflowSessionResult, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Where(entity.WorkflowSessionResultCol.SessionId, sessionId). - Where(entity.WorkflowSessionResultCol.FlowId, flowId). - Where("deleted_at IS NULL"). - OrderDesc(entity.WorkflowSessionResultCol.CreatedAt). - One() - if err != nil { - return - } - err = r.Struct(&res) - return -} - -func (d *workflowSessionResultDao) ListBySession(ctx context.Context, sessionId int64) (res []*entity.WorkflowSessionResult, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Where(entity.WorkflowSessionResultCol.SessionId, sessionId). - Where("deleted_at IS NULL"). - OrderDesc(entity.WorkflowSessionResultCol.CreatedAt). - All() - if err != nil { - return - } - err = r.Structs(&res) - return -} - -func (d *workflowSessionResultDao) ListWorkflowResults(ctx context.Context, creator string, flowId int64, page *beans.Page) (res []*entity.WorkflowSessionResult, total int, err error) { - m := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Where(entity.WorkflowSessionResultCol.Creator, creator). - Where("deleted_at IS NULL") - if flowId != 0 { - m.Where(entity.WorkflowSessionResultCol.FlowId, flowId) - } - m.OrderDesc(entity.WorkflowSessionResultCol.CreatedAt) - if page != nil { - m.Page(int(page.PageNum), int(page.PageSize)) - } - r, total, err := m.AllAndCount(false) - if err != nil { - return - } - err = r.Structs(&res) - return -} - -func (d *workflowSessionResultDao) UpdateRunning(ctx context.Context, id int64) (err error) { - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Data(g.Map{ - entity.WorkflowSessionResultCol.Status: sessionDto.ResultStatusRunning, - entity.WorkflowSessionResultCol.Updater: "", - }). - Where(entity.WorkflowSessionResultCol.Id, id). - Update() - return -} - -func (d *workflowSessionResultDao) UpdateFailed(ctx context.Context, id int64, errorMsg string) (err error) { - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Data(g.Map{ - entity.WorkflowSessionResultCol.Status: sessionDto.ResultStatusFailed, - entity.WorkflowSessionResultCol.ErrorMessage: errorMsg, - entity.WorkflowSessionResultCol.Updater: "", - }). - Where(entity.WorkflowSessionResultCol.Id, id). - Update() - return -} - -func (d *workflowSessionResultDao) UpdateSuccess(ctx context.Context, id int64, resultParams []map[string]any, totalTokens int, totalFee float64) (err error) { - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Data(g.Map{ - entity.WorkflowSessionResultCol.Status: sessionDto.ResultStatusSuccess, - entity.WorkflowSessionResultCol.ResultParams: resultParams, - entity.WorkflowSessionResultCol.TotalTokens: totalTokens, - entity.WorkflowSessionResultCol.TotalFee: totalFee, - entity.WorkflowSessionResultCol.Updater: "", - }). - Where(entity.WorkflowSessionResultCol.Id, id). - Update() - return -} - -func (d *workflowSessionResultDao) SoftDelete(ctx context.Context, id int64) (err error) { - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameWorkflowSessionResult). - Data(g.Map{ - entity.WorkflowSessionResultCol.DeletedAt: gtime.Now(), - entity.WorkflowSessionResultCol.Updater: "", - }). - Where(entity.WorkflowSessionResultCol.Id, id). - Where("deleted_at IS NULL"). - Update() - return -} - -type chatSessionResultDao struct{} - -func (d *chatSessionResultDao) Insert(ctx context.Context, c *entity.ChatSessionResult) (id int64, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameChatSessionResult).Insert(c) - if err != nil { - return - } - return r.LastInsertId() -} - -func (d *chatSessionResultDao) ListBySession(ctx context.Context, sessionId int64) (res []*entity.ChatSessionResult, err error) { - r, err := gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameChatSessionResult). - Where(entity.ChatSessionResultCol.SessionId, sessionId). - Where("deleted_at IS NULL"). - OrderDesc(entity.ChatSessionResultCol.CreatedAt). - All() - if err != nil { - return - } - err = r.Structs(&res) - return -} - -func (d *chatSessionResultDao) SoftDelete(ctx context.Context, id int64) (err error) { - _, err = gfdb.DB(ctx, public.DbNameBlackDeacon).Model(ctx, public.TableNameChatSessionResult). - Data(g.Map{ - entity.ChatSessionResultCol.DeletedAt: gtime.Now(), - entity.ChatSessionResultCol.Updater: "", - }). - Where(entity.ChatSessionResultCol.Id, id). - Where("deleted_at IS NULL"). - Update() - return -} \ No newline at end of file diff --git a/workflow/service/session/session_service.go b/workflow/service/session/session_service.go index fe6b405..5c7c779 100644 --- a/workflow/service/session/session_service.go +++ b/workflow/service/session/session_service.go @@ -5,24 +5,21 @@ import ( sessionDto "ai-agent/workflow/model/dto/session" "ai-agent/workflow/model/entity" "context" - "fmt" "sort" + "strings" "gitea.redpowerfuture.com/red-future/common/utils" - "github.com/gogf/gf/v2/os/gtime" ) var SessionService = &sessionService{} type sessionService struct{} -func (s *sessionService) Create(ctx context.Context, req *sessionDto.CreateSessionReq) (res *sessionDto.CreateSessionRes, err error) { - id, err := sessionDao.SessionDao.Insert(ctx, req) - if err != nil { - return - } - return &sessionDto.CreateSessionRes{Id: id}, nil -} +// 结果状态(与 workflow_session_result.status / VOSessionInfoResult.Status 一致) +const ( + resultStatusSuccess = 2 + resultStatusFailed = 3 +) func (s *sessionService) List(ctx context.Context, req *sessionDto.ListSessionReq) (res *sessionDto.ListSessionRes, err error) { user, err := utils.GetUserInfo(ctx) @@ -45,112 +42,98 @@ func (s *sessionService) List(ctx context.Context, req *sessionDto.ListSessionRe } func (s *sessionService) Delete(ctx context.Context, req *sessionDto.DeleteSessionReq) (err error) { - return sessionDao.SessionDao.DeleteCascade(ctx, req.Id) + _, err = sessionDao.SessionDao.Delete(ctx, req) + return } -// ListSessionResults 会话内全部结果:工作流 + 普通对话混排,按创建时间倒序 -func (s *sessionService) ListSessionResults(ctx context.Context, req *sessionDto.ListSessionResultsReq) (res *sessionDto.ListSessionResultsRes, err error) { - wfList, err := sessionDao.WorkflowSessionResultDao.ListBySession(ctx, req.SessionId) +// Get 会话内结果:普通对话 + 工作流执行混排,按创建时间倒序,分页 +func (s *sessionService) Get(ctx context.Context, req *sessionDto.GetSessionInfoReq) (res *sessionDto.GetSessionInfoRes, err error) { + chatList, err := sessionDao.ExecChatDao.ListBySession(ctx, req.SessionId) if err != nil { return } - chatList, err := sessionDao.ChatSessionResultDao.ListBySession(ctx, req.SessionId) + wfList, err := sessionDao.ExecWorkflowDao.ListBySession(ctx, req.SessionId) if err != nil { return } + wfResultList, err := sessionDao.ExecWorkflowResultDao.ListBySession(ctx, req.SessionId) + if err != nil { + return + } + // 工作流结果按 exec_id 分组,合并到对应执行记录的结果文件URL + resultByExec := make(map[int64][]string) + for _, wr := range wfResultList { + if wr.ResultFileUrl != "" { + resultByExec[wr.ExecId] = append(resultByExec[wr.ExecId], wr.ResultFileUrl) + } + } - type mixed struct { - createdAt *gtime.Time - vo *sessionDto.VOSessionResult - } - var items []mixed - for _, w := range wfList { - items = append(items, mixed{createdAt: w.CreatedAt, vo: wfResultVO(w)}) - } + res = &sessionDto.GetSessionInfoRes{} for _, c := range chatList { - items = append(items, mixed{createdAt: c.CreatedAt, vo: chatResultVO(c)}) + res.List = append(res.List, chatExecVO(c)) } - sort.Slice(items, func(i, j int) bool { - return items[i].createdAt.After(items[j].createdAt) + for _, w := range wfList { + res.List = append(res.List, workflowExecVO(w, strings.Join(resultByExec[w.Id], ","))) + } + sort.Slice(res.List, func(i, j int) bool { + ci, cj := res.List[i].CreatedAt, res.List[j].CreatedAt + if ci == nil { + return false + } + if cj == nil { + return true + } + return ci.After(cj) }) - res = new(sessionDto.ListSessionResultsRes) - for _, it := range items { - res.List = append(res.List, it.vo) + res.Total = len(res.List) + if req.Page != nil && req.Page.PageSize > 0 { + start := int((req.Page.PageNum - 1) * req.Page.PageSize) + if start < 0 { + start = 0 + } + if start >= res.Total { + res.List = nil + return + } + end := start + int(req.Page.PageSize) + if end > res.Total { + end = res.Total + } + res.List = res.List[start:end] } return } -func wfResultVO(w *entity.WorkflowSessionResult) *sessionDto.VOSessionResult { - return &sessionDto.VOSessionResult{ - ResultId: w.Id, +func chatExecVO(c *entity.ExecChat) *sessionDto.VOSessionInfoResult { + status := resultStatusSuccess + if c.ErrorMessage != "" { + status = resultStatusFailed + } + return &sessionDto.VOSessionInfoResult{ + Id: c.Id, + Type: "chat", + Status: status, + RequestParams: map[string]any{"question": c.RequestParams.Question}, + ResultFileUrl: c.ResultFileUrl, + TotalTokens: c.TotalTokens, + TotalFee: c.TotalFee, + ErrorMsg: c.ErrorMessage, + CreatedAt: c.CreatedAt, + } +} + +func workflowExecVO(w *entity.ExecWorkflow, resultFileUrl string) *sessionDto.VOSessionInfoResult { + return &sessionDto.VOSessionInfoResult{ + Id: w.Id, Type: "workflow", Status: w.Status, FlowId: w.FlowId, - FlowName: w.FlowName, RequestParams: w.RequestParams, - ResultParams: w.ResultParams, + ResultFileUrl: resultFileUrl, TotalTokens: w.TotalTokens, TotalFee: w.TotalFee, ErrorMsg: w.ErrorMessage, CreatedAt: w.CreatedAt, } } - -func chatResultVO(c *entity.ChatSessionResult) *sessionDto.VOSessionResult { - status := sessionDto.ResultStatusSuccess - if c.ErrorMessage != "" { - status = sessionDto.ResultStatusFailed - } - return &sessionDto.VOSessionResult{ - ResultId: c.Id, - Type: "chat", - Status: status, - Question: c.Question, - Answer: c.Answer, - TotalTokens: c.TotalTokens, - TotalFee: c.TotalFee, - ErrorMsg: c.ErrorMessage, - CreatedAt: c.CreatedAt, - } -} - -func (s *sessionService) DeleteResult(ctx context.Context, req *sessionDto.DeleteSessionResultReq) (err error) { - switch req.Type { - case "workflow": - return sessionDao.WorkflowSessionResultDao.SoftDelete(ctx, req.Id) - case "chat": - return sessionDao.ChatSessionResultDao.SoftDelete(ctx, req.Id) - default: - return fmt.Errorf("未知结果类型: %s", req.Type) - } -} - -// ListWorkflowResults 工作流维度结果平铺列表(含已删除会话下的结果) -func (s *sessionService) ListWorkflowResults(ctx context.Context, req *sessionDto.ListWorkflowResultsReq) (res *sessionDto.ListWorkflowResultsRes, err error) { - user, err := utils.GetUserInfo(ctx) - if err != nil { - return - } - list, total, err := sessionDao.WorkflowSessionResultDao.ListWorkflowResults(ctx, user.UserName, req.FlowId, req.Page) - if err != nil { - return - } - res = &sessionDto.ListWorkflowResultsRes{Total: total} - for _, w := range list { - res.List = append(res.List, &sessionDto.VOWorkflowResult{ - ResultId: w.Id, - SessionId: w.SessionId, - FlowId: w.FlowId, - FlowName: w.FlowName, - RequestParams: w.RequestParams, - ResultParams: w.ResultParams, - Status: w.Status, - TotalTokens: w.TotalTokens, - TotalFee: w.TotalFee, - ErrorMsg: w.ErrorMessage, - CreatedAt: w.CreatedAt, - }) - } - return -} \ No newline at end of file