diff --git a/README2.md b/README2.md deleted file mode 100644 index 7e93b59..0000000 --- a/README2.md +++ /dev/null @@ -1 +0,0 @@ -您提供的信息中,**图片内容**是一张手机屏幕截图,显示的是一个支付成功的账单详情页面。我们先对这张图片中的信息进行解析和理解,再判断其问题类型、等级,并分析“系统一直在报错”是否与该图相关。\n\n---\n\n### 一、图片内容解析(从截图提取关键信息)\n\n#### 1. **基础信息**\n- **时间**:2024年8月16日 04:09:30\n- **金额**:-1166.00 元(支出)\n- **支付状态**:支付成功\n- **商户名称**:河南联合汇能清洁能源有限公司\n- **商品描述**:加气订单支付\n- **收单机构**:通联支付网络服务股份有限公司\n- **支付方式**:中国银行储蓄卡(9370)\n- **交易单号**:已部分遮挡(可识别为 `2024081611...`)\n- **商户单号**:可在支持的商户扫码退款\n\n#### 2. **附加信息**\n- 手机顶部显示时间为 **2:52**(可能是拍摄时间,非交易时间)\n- 图片右下角有水印:“河北新闻网 Hebnews.cn”\n\n---\n\n### 二、内容理解\n\n这是一笔在 **凌晨4点09分** 完成的 **天然气加气支付记录**,金额为 **1166元**,通过银行卡支付,由“河南联合汇能清洁能源有限公司”作为收款方,经“通联支付”清算完成。\n\n这笔交易是**真实发生的**,且系统显示“支付成功”,说明:\n- 支付流程已完成;\n- 资金已划出;\n- 用户账户已扣款。\n\n---\n\n### 三、问题分析:用户说“系统一直在报错”\n\n#### 1. 是否与该图片相关?\n\n目前来看:\n- 图片展示的是一个**成功的支付结果**,没有报错提示。\n- 界面干净,无异常弹窗或错误码。\n- 付款状态明确为“支付成功”。\n\n👉 **结论**:这张图片本身**不体现系统报错**,反而表明交易已经成功。\n\n但用户说“系统一直在报错”,可能意味着以下几种情况:\n\n| 可能情况 | 分析 |\n|--------|------|\n| ✅ 交易完成后,用户端仍持续收到“支付失败”或“订单异常”提醒 | 这属于**系统反馈异常**,即实际支付成功,但前端未同步状态 |\n| ❌ 用户误以为自己没支付成功,但实际上已扣款 | 需确认是否重复支付或存在混淆 |\n| 🔁 多次尝试支付时,系统反复报错,最终一次成功 | 可能是中间环节出现通信超时等临时故障 |\n| 🧩 支付系统与商户系统对接异常,导致订单状态不同步 | 比如商户后台未收到确认,用户端却显示成功 |\n\n---\n\n### 四、问题类型判断\n\n根据以上分析,该问题属于:\n\n> **【支付系统状态不同步问题】**\n\n具体分类如下:\n\n```json\n{\n \"problem_type\": \"支付系统状态不同步\",\n \"sub_type\": \"前端显示异常 / 后台数据未更新\",\n \"description\": \"用户支付成功后,系统仍持续报错或提示异常,导致用户体验混乱,怀疑交易未成功。\",\n \"possible_causes\": [\n \"支付平台与商户系统接口响应延迟或失败\",\n \"订单状态未及时回传至用户端\",\n \"缓存机制问题导致界面刷新不及时\",\n \"多端系统(APP/小程序/网页)状态不一致\"\n ]\n}\n```\n\n---\n\n### 五、问题等级划分(建议)\n\n| 等级 | 标准 | 本案例评估 |\n|------|------|------------|\n| ⚠️ **P2 - 中等优先级** | 影响用户体验,但不涉及资金损失或安全风险 | ✅ 符合 |\n| ❌ P1 - 高优先级 | 导致资金无法到账、重复扣款、欺诈风险等 | 不符合 |\n| ❌ P3 - 低优先级 | 仅界面轻微显示问题,不影响核心功能 | 不符合 |\n\n> **推荐等级:P2(中等)**\n\n理由:\n- 用户已支付成功,资金安全;\n- 但因系统持续报错,可能导致用户焦虑、重复操作、投诉;\n- 长期存在会影响品牌信誉和服务质量。\n\n---\n\n### 六、建议处理方案\n\n1. **前端排查**:\n - 检查是否有定时轮询接口返回错误;\n - 查看是否有旧订单状态未清除;\n - 强制刷新或手动查询订单状态。\n\n2. **后端对接检查**:\n - 确认支付回调通知是否正确发送到商户系统;\n - 检查商户订单状态更新逻辑是否健壮;\n - 是否存在异步任务失败未重试。\n\n3. **用户沟通**:\n - 提供支付凭证截图(如本图)作为证据;\n - 建议联系客服提供交易单号协助核实;\n - 明确告知“已成功支付,请勿重复操作”。\n\n---\n\n### 总结\n\n| 项目 | 内容 |\n|------|------|\n| 图片内容 | 成功支付1166元加气订单 |\n| 是否报错 | 图片中无报错,支付成功 |\n| 实际问题 | 用户感知“系统一直报错”,可能为状态不同步 |\n| 问题类型 | 支付系统状态不同步 |\n| 问题等级 | P2(中等优先级) |\n| 建议行动 | 排查前后端状态同步机制,加强用户沟通 |\n\n如有更多上下文(如用户多次尝试、支付失败记录、报错截图等),可进一步定位具体原因。 \ No newline at end of file diff --git a/cmd/server/main.go b/cmd/server/main.go index e5fbbdd..f0b0214 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -10,7 +10,7 @@ import ( ) func main() { - configPath := flag.String("config", "./config/config.yaml", "Path to configuration file") + configPath := flag.String("config", "./config/config_test.yaml", "Path to configuration file") flag.Parse() bc, err := config.LoadConfig(*configPath) if err != nil { diff --git a/config/config_test.yaml b/config/config_test.yaml index c005314..ff2d2d8 100644 --- a/config/config_test.yaml +++ b/config/config_test.yaml @@ -7,7 +7,7 @@ ollama: base_url: "http://127.0.0.1:11434" model: "qwen3-coder:480b-cloud" generate_model: "qwen3-coder:480b-cloud" - vl_model: "qwen2.5vl:7b" + vl_model: "qwen2.5vl:3b" timeout: "120s" level: "info" format: "json" diff --git a/gen.sh b/gen.sh index 2004ddd..717d77d 100755 --- a/gen.sh +++ b/gen.sh @@ -16,4 +16,4 @@ -gentool --dsn "root:SD###sdf323r343@tcp(121.199.38.107:3306)/sys_ai?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" -outPath ${modeldir} -onlyModel -modelPkgName "model" -tables ${prefix}${tables} +gentool --dsn "root:SD###sdf323r343@tcp(121.199.38.107:3306)/sys_ai_test?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai" -outPath ${modeldir} -onlyModel -modelPkgName "model" -tables ${prefix}${tables} diff --git a/img.png b/img.png deleted file mode 100644 index 26ca488..0000000 Binary files a/img.png and /dev/null differ diff --git a/internal/biz/chat_history.go b/internal/biz/chat_history.go index 446d68c..48dcd0d 100644 --- a/internal/biz/chat_history.go +++ b/internal/biz/chat_history.go @@ -5,6 +5,8 @@ import ( "ai_scheduler/internal/data/model" "ai_scheduler/internal/entitys" "context" + + "xorm.io/builder" ) type ChatHistoryBiz struct { @@ -15,35 +17,41 @@ func NewChatHistoryBiz(chatRepo *impl.ChatImpl) *ChatHistoryBiz { s := &ChatHistoryBiz{ chatRepo: chatRepo, } - go s.AsyncProcess(context.Background()) + //go s.AsyncProcess(context.Background()) return s } -func (s *ChatHistoryBiz) create(ctx context.Context, sessionID, role, content string) error { - chat := model.AiChatHi{ - SessionID: sessionID, - Role: role, - Content: content, - } - - return s.chatRepo.Create(&chat) -} - -// 添加会话历史 -func (s *ChatHistoryBiz) Create(ctx context.Context, chat entitys.ChatHistory) error { - return s.create(ctx, chat.SessionID, chat.Role.String(), chat.Content) -} +//func (s *ChatHistoryBiz) create(ctx context.Context, sessionID, role, content string) error { +// chat := model.AiChatHi{ +// SessionID: sessionID, +// Role: role, +// Content: content, +// } +// +// return s.chatRepo.Create(&chat) +//} +// +//// 添加会话历史 +//func (s *ChatHistoryBiz) Create(ctx context.Context, chat entitys.ChatHistory) error { +// return s.create(ctx, chat.SessionID, chat.Role.String(), chat.Content) +//} // 异步添加会话历史 -func (s *ChatHistoryBiz) AsyncCreate(ctx context.Context, chat entitys.ChatHistory) { - s.chatRepo.AsyncCreate(ctx, model.AiChatHi{ - SessionID: chat.SessionID, - Role: chat.Role.String(), - Content: chat.Content, - }) -} +//func (s *ChatHistoryBiz) AsyncCreate(ctx context.Context, chat entitys.ChatHistory) { +// s.chatRepo.AsyncCreate(ctx, model.AiChatHi{ +// SessionID: chat.SessionID, +// Role: chat.Role.String(), +// Content: chat.Content, +// }) +//} // 异步处理会话历史 -func (s *ChatHistoryBiz) AsyncProcess(ctx context.Context) { - s.chatRepo.AsyncProcess(ctx) +//func (s *ChatHistoryBiz) AsyncProcess(ctx context.Context) { +// s.chatRepo.AsyncProcess(ctx) +//} + +func (s *ChatHistoryBiz) Update(ctx context.Context, chat *entitys.UseFulRequest) error { + cond := builder.NewCond() + cond = cond.And(builder.Eq{"his_id": chat.HisId}) + return s.chatRepo.UpdateByCond(&cond, &model.AiChatHi{HisID: chat.HisId, Useful: chat.Useful}) } diff --git a/internal/biz/do/ctx.go b/internal/biz/do/ctx.go index 0164da4..a160c8c 100644 --- a/internal/biz/do/ctx.go +++ b/internal/biz/do/ctx.go @@ -94,7 +94,7 @@ func (d *Do) DataAuth(c *websocket.Conn) (err error) { func (d *Do) MakeCh(c *websocket.Conn) (ctx context.Context, deferFunc func()) { d.Ctx.Ch = make(chan entitys.Response) ctx, cancel := context.WithCancel(context.Background()) - done := d.startMessageHandler(ctx, c, d.hisImpl) + done := d.startMessageHandler(ctx, c) return ctx, func() { close(d.Ctx.Ch) //关闭主通道 <-done // 等待消息处理完成 @@ -186,7 +186,7 @@ func (d *Do) getTasks(sysId int32) (tasks []model.AiTask, err error) { func (d *Do) startMessageHandler( ctx context.Context, c *websocket.Conn, - hisImpl *impl.ChatImpl, + ) <-chan struct{} { done := make(chan struct{}) var chat []string @@ -195,23 +195,25 @@ func (d *Do) startMessageHandler( defer func() { close(done) // 保存历史记录 - var his = []*model.AiChatHi{ - { - SessionID: d.Ctx.Session, - Role: "user", - Content: d.Ctx.Req.Text, // 用户输入在外部处理 - }, - } + var ( + hisLog = &entitys.ChatHisLog{} + ) if len(chat) > 0 { - his = append(his, &model.AiChatHi{ + AiRes := &model.AiChatHi{ SessionID: d.Ctx.Session, - Role: "assistant", - Content: strings.Join(chat, ""), - }) - } - for _, hi := range his { - hisImpl.Add(hi) + Ques: d.Ctx.Req.Text, + Ans: strings.Join(chat, ""), + Files: d.Ctx.Req.Img, + } + d.hisImpl.AddWithData(AiRes) + hisLog.HisId = AiRes.HisID } + + _ = entitys.MsgSend(c, entitys.Response{ + Content: pkg.JsonStringIgonErr(hisLog), + Type: entitys.ResponseEnd, + }) + }() for v := range d.Ctx.Ch { // 自动检测通道关闭 diff --git a/internal/biz/do/handle.go b/internal/biz/do/handle.go index 73e304e..4c2803d 100644 --- a/internal/biz/do/handle.go +++ b/internal/biz/do/handle.go @@ -90,7 +90,7 @@ func (r *Handle) HandleMatch(ctx context.Context, requireData *entitys.RequireDa if pointTask == nil || pointTask.Index == "other" { return r.OtherTask(ctx, requireData) } - switch pointTask.Type { + switch constants.TaskType(pointTask.Type) { case constants.TaskTypeApi: return r.handleApiTask(ctx, requireData, pointTask) case constants.TaskTypeFunc: diff --git a/internal/biz/llm_service/common.go b/internal/biz/llm_service/common.go index d833f51..f10406b 100644 --- a/internal/biz/llm_service/common.go +++ b/internal/biz/llm_service/common.go @@ -1,9 +1,11 @@ package llm_service import ( + "ai_scheduler/internal/data/constants" "ai_scheduler/internal/data/model" "ai_scheduler/internal/entitys" "context" + "time" ) type LlmService interface { @@ -24,11 +26,18 @@ func buildAssistant(his []model.AiChatHi) (chatHis entitys.ChatHis) { if len(chatHis.SessionId) == 0 { chatHis.SessionId = item.SessionID } - chatHis.Messages = append(chatHis.Messages, entitys.HisMessage{ - Role: item.Role, - Content: item.Content, - Timestamp: item.CreateAt.Format("2006-01-02 15:04:05"), - }) + chatHis.Messages = append(chatHis.Messages, []entitys.HisMessage{ + { + Role: constants.RoleUser, + Content: item.Ques, + Timestamp: item.CreateAt.Format(time.DateTime), + }, + { + Role: constants.RoleAssistant, + Content: item.Ans, + Timestamp: item.CreateAt.Format(time.DateTime), + }, + }...) } chatHis.Context = entitys.HisContext{ UserLanguage: "zh-CN", @@ -36,3 +45,23 @@ func buildAssistant(his []model.AiChatHi) (chatHis entitys.ChatHis) { } return } + +func BuildChatHisMessage(his []model.AiChatHi) (chatHis []entitys.HisMessage) { + for _, item := range his { + + chatHis = append(chatHis, []entitys.HisMessage{ + { + Role: constants.RoleUser, + Content: item.Ques, + Timestamp: item.CreateAt.Format(time.DateTime), + }, + { + Role: constants.RoleAssistant, + Content: item.Ans, + Timestamp: item.CreateAt.Format(time.DateTime), + }, + }...) + } + + return +} diff --git a/internal/biz/llm_service/ollama.go b/internal/biz/llm_service/ollama.go index 25791da..60d9c78 100644 --- a/internal/biz/llm_service/ollama.go +++ b/internal/biz/llm_service/ollama.go @@ -2,6 +2,7 @@ package llm_service import ( "ai_scheduler/internal/config" + "ai_scheduler/internal/data/impl" "ai_scheduler/internal/data/model" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg" @@ -13,20 +14,24 @@ import ( "time" "github.com/ollama/ollama/api" + "xorm.io/builder" ) type OllamaService struct { - client *utils_ollama.Client - config *config.Config + client *utils_ollama.Client + config *config.Config + chatHis *impl.ChatImpl } func NewOllamaGenerate( client *utils_ollama.Client, config *config.Config, + chatHis *impl.ChatImpl, ) *OllamaService { return &OllamaService{ - client: client, - config: config, + client: client, + config: config, + chatHis: chatHis, } } @@ -66,6 +71,10 @@ func (r *OllamaService) getPrompt(ctx context.Context, requireData *entitys.Requ var ( prompt = make([]api.Message, 0) ) + content, err := r.getUserContent(ctx, requireData) + if err != nil { + return nil, err + } prompt = append(prompt, api.Message{ Role: "system", Content: buildSystemPrompt(requireData.Sys.SysPrompt), @@ -74,32 +83,17 @@ func (r *OllamaService) getPrompt(ctx context.Context, requireData *entitys.Requ Content: "### 聊天记录:" + pkg.JsonStringIgonErr(buildAssistant(requireData.Histories)), }, api.Message{ Role: "user", - Content: r.getUserContent(requireData), - //Images: requireData.ImgByte, + Content: content, }) - if len(requireData.ImgByte) > 0 { - desc, err := r.RecognizeWithImg(ctx, requireData) - if err != nil { - return nil, err - } - var imgs strings.Builder - imgs.WriteString("### 用户上传图片解析内容:\n") - - prompt = append(prompt, api.Message{ - Role: "image_desc", - Content: "" + desc.Response, - }) - } return prompt, nil } -func (r *OllamaService) getUserContent(requireData *entitys.RequireData) string { +func (r *OllamaService) getUserContent(ctx context.Context, requireData *entitys.RequireData) (string, error) { var content strings.Builder content.WriteString(requireData.Req.Text) if len(requireData.ImgByte) > 0 { content.WriteString("\n") - content.WriteString("### 图片内容已经解析到image_desc里") } if len(requireData.Req.Tags) > 0 { @@ -107,7 +101,29 @@ func (r *OllamaService) getUserContent(requireData *entitys.RequireData) string content.WriteString("### 工具必须使用:") content.WriteString(requireData.Req.Tags) } - return content.String() + + if len(requireData.ImgByte) > 0 { + desc, err := r.RecognizeWithImg(ctx, requireData) + if err != nil { + return "", err + } + content.WriteString("### 上传图片解析内容:\n") + content.WriteString(requireData.Req.Tags) + content.WriteString(desc.Response) + } + + if requireData.Req.MarkHis > 0 { + var his model.AiChatHi + cond := builder.NewCond() + cond = cond.And(builder.Eq{"his_id": requireData.Req.MarkHis}) + err := r.chatHis.GetOneBySearchToStrut(&cond, &his) + if err != nil { + return "", err + } + content.WriteString("### 引用历史聊天记录:\n") + content.WriteString(pkg.JsonStringIgonErr(BuildChatHisMessage([]model.AiChatHi{his}))) + } + return content.String(), nil } func (r *OllamaService) RecognizeWithImg(ctx context.Context, requireData *entitys.RequireData) (desc api.GenerateResponse, err error) { diff --git a/internal/biz/session.go b/internal/biz/session.go index 19b3e8a..d014148 100644 --- a/internal/biz/session.go +++ b/internal/biz/session.go @@ -80,11 +80,11 @@ func (s *SessionBiz) SessionInit(ctx context.Context, req *entitys.SessionInitRe result.Prologue = sysConfig.Prologue // 开场白写入会话历史 - s.chatRepo.AsyncCreate(ctx, model.AiChatHi{ - SessionID: chat.SessionID, - Role: chat.Role.String(), - Content: chat.Content, - }) + //s.chatRepo.AsyncCreate(ctx, model.AiChatHi{ + // SessionID: chat.SessionID, + // Role: chat.Role.String(), + // Content: chat.Content, + //}) } else { result.SessionId = session.SessionID @@ -102,12 +102,20 @@ func (s *SessionBiz) SessionInit(ctx context.Context, req *entitys.SessionInitRe // 转换为 entitys.ChatHistory 类型 for _, chat := range chatList { - result.Chat = append(result.Chat, entitys.ChatHistory{ - SessionID: chat.SessionID, - Role: constants.Caller(chat.Role), - Content: chat.Content, - Prologue: sysConfig.Prologue, - }) + result.Chat = append(result.Chat, []entitys.ChatHistory{ + { + SessionID: chat.SessionID, + Role: constants.RoleUser, + Content: chat.Ques, + Prologue: sysConfig.Prologue, + }, + { + SessionID: chat.SessionID, + Role: constants.RoleAssistant, + Content: chat.Ans, + Prologue: sysConfig.Prologue, + }, + }...) } } diff --git a/internal/data/constants/const.go b/internal/data/constants/const.go index 6b3df7a..f06e906 100644 --- a/internal/data/constants/const.go +++ b/internal/data/constants/const.go @@ -11,8 +11,22 @@ const ( type TaskType int32 const ( - TaskTypeApi = 1 - TaskTypeKnowle = 2 - TaskTypeFunc = 3 - TaskTypeBot = 4 + TaskTypeApi TaskType = 1 + TaskTypeKnowle TaskType = 2 + TaskTypeFunc TaskType = 3 + TaskTypeBot TaskType = 4 ) + +type UseFul int32 + +const ( + UseFulNotSolve UseFul = 2 + UseFulNotUnclear UseFul = 3 + UseFulNotError UseFul = 4 +) + +var UseFulMap = map[UseFul]string{ + UseFulNotSolve: "未解决问题", + UseFulNotUnclear: "回答不明确", + UseFulNotError: "理解错误", +} diff --git a/internal/data/model/ai_chat_his.gen.go b/internal/data/model/ai_chat_his.gen.go index de2b641..d143972 100644 --- a/internal/data/model/ai_chat_his.gen.go +++ b/internal/data/model/ai_chat_his.gen.go @@ -12,11 +12,14 @@ const TableNameAiChatHi = "ai_chat_his" // AiChatHi mapped from table type AiChatHi struct { - HisID int64 `gorm:"column:his_id;primaryKey" json:"his_id"` - SessionID string `gorm:"column:session_id;not null" json:"session_id"` - Role string `gorm:"column:role;not null;comment:system系统输出,assistant助手输出,user用户输入" json:"role"` // system系统输出,assistant助手输出,user用户输入 - Content string `gorm:"column:content;not null" json:"content"` - CreateAt *time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"` + HisID int64 `gorm:"column:his_id;primaryKey;autoIncrement:true" json:"his_id"` + SessionID string `gorm:"column:session_id;not null" json:"session_id"` + Ques string `gorm:"column:ques;not null" json:"ques"` + Ans string `gorm:"column:ans;not null" json:"ans"` + Files string `gorm:"column:files;not null" json:"files"` + Useful int32 `gorm:"column:useful;not null;comment:0不评价,1有用,其他为无用" json:"useful"` // 0不评价,1有用,其他为无用 + CreateAt time.Time `gorm:"column:create_at;default:CURRENT_TIMESTAMP" json:"create_at"` + UpdatedAt time.Time `gorm:"column:updated_at;default:CURRENT_TIMESTAMP" json:"updated_at"` } // TableName AiChatHi's table name diff --git a/internal/entitys/chat_history.go b/internal/entitys/chat_history.go index baa4adf..a26fa46 100644 --- a/internal/entitys/chat_history.go +++ b/internal/entitys/chat_history.go @@ -10,3 +10,7 @@ type ChatHistory struct { Content string `json:"content"` Prologue string `json:"prologue"` } + +type ChatHisLog struct { + HisId int64 `json:"his_id"` +} diff --git a/internal/entitys/session.go b/internal/entitys/session.go index e02ddb9..0527329 100644 --- a/internal/entitys/session.go +++ b/internal/entitys/session.go @@ -23,3 +23,8 @@ type SessionListRequest struct { type TaskRequest struct { SysId int32 `json:"sys_id"` } + +type UseFulRequest struct { + HisId int64 `json:"his_id"` + Useful int32 `json:"useful"` +} diff --git a/internal/entitys/types.go b/internal/entitys/types.go index 64de5a2..ece5ceb 100644 --- a/internal/entitys/types.go +++ b/internal/entitys/types.go @@ -1,6 +1,7 @@ package entitys import ( + "ai_scheduler/internal/data/constants" "ai_scheduler/internal/data/model" "context" @@ -31,7 +32,9 @@ type FirstSockRequest struct { type ChatSockRequest struct { Text string `json:"text" binding:"required"` Img string `json:"img" binding:"required"` + File string `json:"file" binding:"required"` Tags string `json:"tags" binding:"required"` + MarkHis int64 `json:"mark_his" ` Caller string `json:"caller" binding:"required"` SessionID string `json:"session_id"` } @@ -130,9 +133,9 @@ type ChatHis struct { Context HisContext `json:"context"` } type HisMessage struct { - Role string `json:"role"` - Content string `json:"content"` - Timestamp string `json:"timestamp"` + Role constants.Caller `json:"role"` + Content string `json:"content"` + Timestamp string `json:"timestamp"` } type HisContext struct { diff --git a/internal/server/router/router.go b/internal/server/router/router.go index a2bbd81..5c935d7 100644 --- a/internal/server/router/router.go +++ b/internal/server/router/router.go @@ -50,9 +50,13 @@ func SetupRoutes(app *fiber.App, ChatService *services.ChatService, sessionServi r.Post("/session/init", sessionService.SessionInit) // 会话初始化,不存在则创建,存在则返回会话ID和默认条数会话历史 r.Post("/session/list", sessionService.SessionList) + r.Post("/sys/tasks", task.Tasks) - // 回调 - r.Post("/callback", callbackService.Callback) + // 评价 + r.Post("/chat/useful/list", ChatService.UsefulList) + r.Post("/chat/useful", ChatService.Useful) + // 回调 + r.Post("/callback", callbackService.Callback) //广播 r.Get("/broadcast", func(ctx *fiber.Ctx) error { action := ctx.Query("action") diff --git a/internal/services/chat.go b/internal/services/chat.go index 06925e2..95cd130 100644 --- a/internal/services/chat.go +++ b/internal/services/chat.go @@ -13,6 +13,7 @@ import ( "sync" "time" + "github.com/gofiber/fiber/v2" "github.com/gofiber/websocket/v2" ) @@ -21,13 +22,19 @@ type ChatService struct { routerBiz *biz.AiRouterBiz Gw *gateway.Gateway mu sync.Mutex + ChatHis *biz.ChatHistoryBiz } // NewChatHandler 创建聊天处理器 -func NewChatService(routerService *biz.AiRouterBiz, gw *gateway.Gateway) *ChatService { +func NewChatService( + routerService *biz.AiRouterBiz, + chatHis *biz.ChatHistoryBiz, + gw *gateway.Gateway, +) *ChatService { return &ChatService{ routerBiz: routerService, Gw: gw, + ChatHis: chatHis, } } @@ -118,10 +125,7 @@ func (h *ChatService) Chat(c *websocket.Conn) { Type: entitys.ResponseText, }) } - _ = entitys.MsgSend(c, entitys.Response{ - Content: "", - Type: entitys.ResponseEnd, - }) + } h.Gw.RemoveClient(clientID) _ = c.Close() @@ -148,3 +152,23 @@ func (h *ChatService) handleMessageToString(c *websocket.Conn, msgType int, msg } return msg.([]byte), constants.ConnStatusIgnore } + +func (s *ChatService) Useful(c *fiber.Ctx) error { + req := &entitys.UseFulRequest{} + if err := c.BodyParser(req); err != nil { + return err + } + + err := s.ChatHis.Update(c.Context(), req) + + if err != nil { + return err + } + + return nil +} + +func (s *ChatService) UsefulList(c *fiber.Ctx) error { + + return c.JSON(constants.UseFulMap) +} diff --git a/tmpl/dataTemp/queryTempl.go b/tmpl/dataTemp/queryTempl.go index 2415755..7185bc2 100644 --- a/tmpl/dataTemp/queryTempl.go +++ b/tmpl/dataTemp/queryTempl.go @@ -68,6 +68,14 @@ func (k DataTemp) Add(data interface{}) (id int, err error) { return primary.Id, add.Error } +func (k DataTemp) AddWithData(data interface{}) (interface{}, error) { + result := k.Db.Model(k.Model).Create(data) + if result.Error != nil { + return data, result.Error + } + return data, nil +} + func (k DataTemp) GetList(cond *builder.Cond, pageBoIn *ReqPageBo) (list []map[string]interface{}, pageBoOut *RespPageBo, err error) { var ( query, _ = builder.ToBoundSQL(*cond)