kobe6258 1 月之前
父节点
当前提交
5a2782b1ac

+ 3 - 45
controllers/rag/chat_controller.go → controllers/rag/chat_ws_controller.go

@@ -1,10 +1,8 @@
 package rag
 package rag
 
 
 import (
 import (
-	"encoding/json"
 	"eta/eta_api/controllers"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
 	"eta/eta_api/models"
-	"eta/eta_api/models/llm"
 	"eta/eta_api/models/system"
 	"eta/eta_api/models/system"
 	"eta/eta_api/services/llm/facade"
 	"eta/eta_api/services/llm/facade"
 	"eta/eta_api/utils"
 	"eta/eta_api/utils"
@@ -17,11 +15,11 @@ import (
 	"time"
 	"time"
 )
 )
 
 
-type ChatController struct {
+type ChatWsController struct {
 	controllers.BaseAuthController
 	controllers.BaseAuthController
 }
 }
 
 
-func (cc *ChatController) Prepare() {
+func (cc *ChatWsController) Prepare() {
 	method := cc.Ctx.Input.Method()
 	method := cc.Ctx.Input.Method()
 	uri := cc.Ctx.Input.URI()
 	uri := cc.Ctx.Input.URI()
 	if method == "GET" {
 	if method == "GET" {
@@ -142,51 +140,11 @@ func (cc *ChatController) Prepare() {
 	}
 	}
 }
 }
 
 
-// NewChat @Title 新建对话框
-// @Description 新建对话框
-// @Success 101 {object} response.ListResp
-// @router /chat/new_chat [post]
-func (kbctrl *KbController) NewChat() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		kbctrl.Data["json"] = br
-		kbctrl.ServeJSON()
-	}()
-	var req facade.LLMKnowledgeSearch
-	err := json.Unmarshal(kbctrl.Ctx.Input.RequestBody, &req)
-	if err != nil {
-		br.Msg = "参数解析异常!"
-		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-		return
-	}
-	sysUser := kbctrl.SysUser
-	if sysUser == nil {
-		br.Msg = "请登录"
-		br.ErrMsg = "请登录,SysUser Is Empty"
-		br.Ret = 408
-		return
-	}
-	session := llm.UserLlmChat{
-		UserId:      sysUser.AdminId,
-		CreatedTime: time.Now(),
-		ChatTitle:   "新会话",
-	}
-	err = session.CreateChatSession()
-	if err != nil {
-		br.Msg = "创建失败"
-		br.ErrMsg = "创建失败,Err:" + err.Error()
-		return
-	}
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "创建成功"
-}
-
 // ChatConnect @Title 知识库问答创建对话连接
 // ChatConnect @Title 知识库问答创建对话连接
 // @Description 知识库问答创建对话连接
 // @Description 知识库问答创建对话连接
 // @Success 101 {object} response.ListResp
 // @Success 101 {object} response.ListResp
 // @router /chat/connect [get]
 // @router /chat/connect [get]
-func (cc *ChatController) ChatConnect() {
+func (cc *ChatWsController) ChatConnect() {
 	if !ws.Allow(cc.SysUser.AdminId, ws.CONNECT_LIMITER) {
 	if !ws.Allow(cc.SysUser.AdminId, ws.CONNECT_LIMITER) {
 		utils.FileLog.Error("WebSocket连接太频繁,主动拒绝链接")
 		utils.FileLog.Error("WebSocket连接太频繁,主动拒绝链接")
 		cc.Ctx.ResponseWriter.WriteHeader(http.StatusTooManyRequests)
 		cc.Ctx.ResponseWriter.WriteHeader(http.StatusTooManyRequests)

+ 2 - 1
controllers/rag/llm_http/request.go

@@ -6,6 +6,7 @@ type LLMQuestionReq struct {
 	SessionId     string `description:"会话ID"`
 	SessionId     string `description:"会话ID"`
 }
 }
 
 
-type CreateChatReq struct {
+type UserChatReq struct {
+	ChatId   int    `json:"ChatId"`
 	ChatTitle string `json:"ChatTitle" description:"会话名称"`
 	ChatTitle string `json:"ChatTitle" description:"会话名称"`
 }
 }

+ 145 - 0
controllers/rag/user_chat_controller.go

@@ -0,0 +1,145 @@
+package rag
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/controllers/rag/llm_http"
+	"eta/eta_api/models"
+	"eta/eta_api/models/llm"
+	"eta/eta_api/utils"
+	"time"
+)
+
+type UserChatController struct {
+	controllers.BaseAuthController
+}
+
+// NewChat @Title 新建对话框
+// @Description 新建对话框
+// @Success 101 {object} response.ListResp
+// @router /chat/new_chat [post]
+func (ucCtrl *UserChatController) NewChat() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		ucCtrl.Data["json"] = br
+		ucCtrl.ServeJSON()
+	}()
+	var req llm_http.UserChatReq
+	err := json.Unmarshal(ucCtrl.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	sysUser := ucCtrl.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	if req.ChatTitle == "" {
+		req.ChatTitle = "新会话"
+	}
+	session := llm.UserLlmChat{
+		UserId:      sysUser.AdminId,
+		CreatedTime: time.Now(),
+		ChatTitle:   req.ChatTitle,
+	}
+	err = session.CreateChatSession()
+	if err != nil {
+		br.Msg = "创建失败"
+		br.ErrMsg = "创建失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "创建成功"
+}
+
+// RenameChat @Title 新建对话框
+// @Description 新建对话框
+// @Success 101 {object} response.ListResp
+// @router /chat/rename_chat [post]
+func (ucCtrl *UserChatController) RenameChat() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		ucCtrl.Data["json"] = br
+		ucCtrl.ServeJSON()
+	}()
+	var req llm_http.UserChatReq
+	err := json.Unmarshal(ucCtrl.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	sysUser := ucCtrl.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	if req.ChatId <= 0 {
+		br.Msg = "非法的对话框Id"
+		br.ErrMsg = "非法的对话框Id"
+		return
+	}
+	if req.ChatTitle == "" {
+		br.Msg = "重命名不能为空"
+		br.ErrMsg = "重命名不能为空"
+		return
+	}
+	session := llm.UserLlmChat{
+		Id:         req.ChatId,
+		UpdateTime: time.Now(),
+		UserId:     sysUser.AdminId,
+		ChatTitle:  req.ChatTitle,
+	}
+	err = session.RenameChatSession()
+	if err != nil {
+		br.Msg = "重命名失败"
+		br.ErrMsg = "重命名失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "重命名成功"
+}
+
+// GetUserChatList @Title 获取用户对话框列表
+// @Description  获取用户对话框列表
+// @Success 101 {object} response.ListResp
+// @router /chat/user_chat_list [get]
+func (ucCtrl *UserChatController) GetUserChatList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		ucCtrl.Data["json"] = br
+		ucCtrl.ServeJSON()
+	}()
+	sysUser := ucCtrl.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	//周日是0,周六是6
+	toDay := time.Now().Weekday()
+	offset := int(time.Monday - toDay)
+	if offset > 0 {
+		offset -= 7
+	}
+	monDay := time.Now().AddDate(0, 0, offset).Format(utils.FormatDate)
+	chatList, err := llm.GetUserChatList(sysUser.AdminId, monDay, time.Now().Format(utils.FormatDate))
+	if err != nil {
+		br.Msg = "重命名失败"
+		br.ErrMsg = "重命名失败,Err:" + err.Error()
+		return
+	}
+	br.Data = chatList
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "重命名成功"
+}

+ 17 - 0
models/llm/user_chat_record.go

@@ -0,0 +1,17 @@
+package llm
+
+import "time"
+
+// UserChatRecord 定义用户聊天记录结构体
+type UserChatRecord struct {
+	Id           int       `gorm:"primaryKey;autoIncrement;comment:主键"`
+	ChatId       int       `gorm:"comment:会话id"`
+	ChatUserType string    `gorm:"type:enum('user','assistant');comment:用户方"`
+	SendTime     time.Time `gorm:"comment:发送时间"`
+	CreatedTime  time.Time `gorm:"comment:创建时间"`
+	UpdateTime   time.Time `gorm:"autoUpdateTime;comment:更新时间"`
+}
+
+func (u *UserChatRecord) TableName() string {
+	return "user_chat_record"
+}

+ 23 - 0
models/llm/user_llm_chat.go

@@ -1,6 +1,7 @@
 package llm
 package llm
 
 
 import (
 import (
+	"errors"
 	"eta/eta_api/global"
 	"eta/eta_api/global"
 	"eta/eta_api/utils"
 	"eta/eta_api/utils"
 	"time"
 	"time"
@@ -23,3 +24,25 @@ func (u *UserLlmChat) CreateChatSession() (err error) {
 	err = o.Create(u).Error
 	err = o.Create(u).Error
 	return
 	return
 }
 }
+func (u *UserLlmChat) RenameChatSession() (err error) {
+	o := global.DbMap[utils.DbNameAI]
+	var exists bool
+	err = o.Model(&u).Select("1").Where("id = ?", u.Id).Scan(&exists).Error
+	if err != nil {
+		return
+	}
+	if !exists {
+		err = errors.New("当前会话不存在")
+		return
+	}
+	err = o.Select("chat_title").Updates(u).Error
+	return
+}
+
+func GetUserChatList(userId int, monDay, toDay string) (chatList []UserLlmChat, err error) {
+	o := global.DbMap[utils.DbNameAI]
+	sql := `select ulc.id ,ulc.chat_title,ulc.created_time,COUNT(ucr.id) AS record_count from user_llm_chat ulc left join user_chat_record ucr
+    ON ucr.chat_id = ulc.id where ulc.user_id=? and ? BETWEEN ? and ? GROUP BY ulc.id`
+	err = o.Raw(sql, userId, utils.GenerateQuerySql(utils.ToDate, &utils.QueryParam{Column: "ulc.created_time"}), monDay, toDay).Find(&chatList).Error
+	return
+}

+ 30 - 11
routers/commentsRouter.go

@@ -8521,7 +8521,7 @@ func init() {
             Filters: nil,
             Filters: nil,
             Params: nil})
             Params: nil})
 
 
-    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:ChatController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:ChatController"],
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:ChatWsController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:ChatWsController"],
         beego.ControllerComments{
         beego.ControllerComments{
             Method: "ChatConnect",
             Method: "ChatConnect",
             Router: `/chat/connect`,
             Router: `/chat/connect`,
@@ -8530,15 +8530,6 @@ func init() {
             Filters: nil,
             Filters: nil,
             Params: nil})
             Params: nil})
 
 
-    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"],
-        beego.ControllerComments{
-            Method: "NewChat",
-            Router: `/chat/new_chat`,
-            AllowHTTPMethods: []string{"post"},
-            MethodParams: param.Make(),
-            Filters: nil,
-            Params: nil})
-
     beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"],
     beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:KbController"],
         beego.ControllerComments{
         beego.ControllerComments{
             Method: "SearchDocs",
             Method: "SearchDocs",
@@ -8584,6 +8575,33 @@ func init() {
             Filters: nil,
             Filters: nil,
             Params: nil})
             Params: nil})
 
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"],
+        beego.ControllerComments{
+            Method: "NewChat",
+            Router: `/chat/new_chat`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"],
+        beego.ControllerComments{
+            Method: "RenameChat",
+            Router: `/chat/rename_chat`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:UserChatController"],
+        beego.ControllerComments{
+            Method: "GetUserChatList",
+            Router: `/chat/user_chat_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"],
     beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/rag:WechatPlatformController"],
         beego.ControllerComments{
         beego.ControllerComments{
             Method: "TagList",
             Method: "TagList",
@@ -13191,4 +13209,5 @@ func init() {
             MethodParams: param.Make(),
             MethodParams: param.Make(),
             Filters: nil,
             Filters: nil,
             Params: nil})
             Params: nil})
-}
+
+}

+ 3 - 4
routers/router.go

@@ -69,13 +69,12 @@ func init() {
 		),
 		),
 		web.NSNamespace("/llm",
 		web.NSNamespace("/llm",
 			web.NSInclude(
 			web.NSInclude(
-				&rag.ChatController{},
+				&rag.ChatWsController{},
+				&rag.UserChatController{},
+				&rag.KbController{},
 				&rag.WechatPlatformController{},
 				&rag.WechatPlatformController{},
 				&rag.QuestionController{},
 				&rag.QuestionController{},
 			),
 			),
-			web.NSInclude(
-				&rag.KbController{},
-			),
 		),
 		),
 		web.NSNamespace("/banner",
 		web.NSNamespace("/banner",
 			web.NSInclude(
 			web.NSInclude(

+ 72 - 0
utils/sql.go

@@ -20,6 +20,8 @@ const (
 	Order         SqlCondition = "Order"
 	Order         SqlCondition = "Order"
 	Delimiter     SqlCondition = "Delimiter"
 	Delimiter     SqlCondition = "Delimiter"
 	ConvertColumn SqlCondition = "ConvertColumn"
 	ConvertColumn SqlCondition = "ConvertColumn"
+
+	ToDate SqlCondition = "ToDate"
 )
 )
 
 
 var TemplateMap = map[SqlCondition]map[Driver]string{
 var TemplateMap = map[SqlCondition]map[Driver]string{
@@ -31,6 +33,10 @@ var TemplateMap = map[SqlCondition]map[Driver]string{
 		MySql: `CONVERT({{.ConvertColumn}} USING gbk )`,
 		MySql: `CONVERT({{.ConvertColumn}} USING gbk )`,
 		DM:    `{{.ConvertColumn}}`,
 		DM:    `{{.ConvertColumn}}`,
 	},
 	},
+	ToDate: {
+		MySql: `DATE({{.Column}})`,
+		DM:    `TO_DATE({{.Column}})`,
+	},
 }
 }
 
 
 var supportDriverMap = map[string]Driver{
 var supportDriverMap = map[string]Driver{
@@ -67,6 +73,71 @@ func (distinctParam *DistinctParam) GetFormatConditionStr(param *QueryParam) str
 	return ""
 	return ""
 }
 }
 
 
+type ToDateParam struct {
+}
+
+func (toDateParam *ToDateParam) GetParamName() string {
+	return "ToDate"
+}
+func (toDateParam *ToDateParam) GetFormatConditionStr(param *QueryParam) (sql string) {
+	dbDriver, _ := getDriverInstance(param.Driver)
+	if param.Column == "" {
+		FileLog.Error("聚合字段为空,无法生成聚合sql")
+		return
+	}
+	var templateSqlStr string
+	if _, ok := TemplateMap[ToDate][dbDriver]; !ok {
+		templateSqlStr = TemplateMap[ToDate][MySql]
+	} else {
+		templateSqlStr = TemplateMap[ToDate][dbDriver]
+	}
+	if templateSqlStr == "" {
+		FileLog.Error("聚合sql模板不存在,无法生成聚合sql")
+		return
+	}
+	templateSql, err := template.New("ToDate").Parse(templateSqlStr)
+	if err != nil {
+		FileLog.Error("failed to parse template: %v", err)
+		return
+	}
+	//反射获取结构体的值
+	value := reflect.ValueOf(param)
+	// 检查是否是指针
+	if value.Kind() != reflect.Ptr {
+		fmt.Println("请求参数必须是一个结构体")
+		return
+	}
+	// 获取结构体的元素
+	elem := value.Elem()
+	// 检查是否是结构体
+	if elem.Kind() != reflect.Struct {
+		fmt.Println("请求参数必须是一个结构体")
+		return
+	}
+	// 获取字段的值
+	fieldValue := elem.FieldByName("ConvertColumn")
+	// 检查字段是否存在
+	if !fieldValue.IsValid() {
+		fmt.Printf("Error: field %s not found\n", "ConvertColumn")
+		return
+	}
+	// 检查字段是否可导出
+	if !fieldValue.CanSet() {
+		fmt.Printf("Error: field %s is not exported and cannot be set\n", "ConvertColumn")
+		return
+	}
+	// 渲染模板
+	var buf bytes.Buffer
+	err = templateSql.Execute(&buf, param)
+	if err != nil {
+		fmt.Sprintf("执行模板填充失败: %v", err)
+		return
+	}
+	sql = buf.String()
+	fmt.Printf("生成的转换日期语句为:%s\n", sql)
+	return sql
+}
+
 type ConvertParam struct {
 type ConvertParam struct {
 }
 }
 
 
@@ -145,6 +216,7 @@ var sqlGeneratorFactory = map[SqlCondition]SqlParam{
 	Delimiter:     &DelimiterParam{},
 	Delimiter:     &DelimiterParam{},
 	Distinct:      &DistinctParam{},
 	Distinct:      &DistinctParam{},
 	ConvertColumn: &ConvertParam{},
 	ConvertColumn: &ConvertParam{},
+	ToDate:        &ToDateParam{},
 }
 }
 
 
 type DelimiterParam struct {
 type DelimiterParam struct {