package ai

import (
	"encoding/json"
	"eta/eta_api/models"
	"eta/eta_api/models/ai_summary"
	"eta/eta_api/models/aimod"
	"eta/eta_api/models/sandbox"
	saModel "eta/eta_api/models/semantic_analysis"
	aiSummaryService "eta/eta_api/services/ai_summary"
	"eta/eta_api/services/aiser"
	"eta/eta_api/utils"
	"fmt"
	"strconv"
	"time"

	"github.com/rdlucklib/rdluck_tools/paging"
)

// AiSummaryClassifyItems
// @Title 获取所有ai纪要分类接口
// @Description 获取所有ai纪要分类接口
// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
// @Success 200 {object} data_manage.ChartClassifyListResp
// @router /summary/classify/list [get]
func (this *AiController) AiSummaryClassifyItems() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	resp := new(ai_summary.AiSummaryClassifyListResp)
	aiSummaryClassifyId, _ := this.GetInt("AiSummaryClassifyId")

	isShowMe, _ := this.GetBool("IsShowMe")
	if isShowMe {
		errMsg, err := aiSummaryService.GetAiSummaryClassifyListForMe(*this.SysUser, resp, aiSummaryClassifyId)
		if err != nil {
			br.Msg = errMsg
			br.ErrMsg = err.Error()
			return
		}
		nodeAll, err := aiSummaryService.GetAiSummaryClassifyByIsShowMe(resp.AllNodes, aiSummaryClassifyId, this.SysUser.AdminId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取数据失败,Err:" + err.Error()
			return
		}
		resp.AllNodes = nodeAll

		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		br.Data = resp
		fmt.Println("source my classify")
		return
	}

	rootList, err := ai_summary.GetAiSummaryClassifyAndInfoByParentId(aiSummaryClassifyId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}
	for k := range rootList {
		rootList[k].UniqueCode = strconv.Itoa(rootList[k].AiSummaryClassifyId) + "_" + strconv.Itoa(rootList[k].AiSummaryId)
	}

	classifyAll, err := ai_summary.GetAiSummaryClassifyAndInfoByParentId(aiSummaryClassifyId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}
	for k := range classifyAll {
		classifyAll[k].UniqueCode = strconv.Itoa(classifyAll[k].AiSummaryClassifyId) + "_" + strconv.Itoa(classifyAll[k].AiSummaryId)
	}

	nodeAll := make([]*ai_summary.AiSummaryClassifyItems, 0)
	for k := range rootList {
		rootNode := rootList[k]
		aiSummaryService.AiSummaryClassifyItemsMakeTreeV2(this.SysUser, classifyAll, rootNode)
		nodeAll = append(nodeAll, rootNode)
	}

	resp.AllNodes = nodeAll
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// @Title 新增ai纪要分类
// @Description 新增ai纪要分类接口
// @Param	request	body data_manage.AddChartClassifyReq true "type json string"
// @Success 200 Ret=200 保存成功
// @router /summary/classify/add [post]
func (this *AiController) AddAiSummaryClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req ai_summary.AddAiSummaryClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.ClassifyName == "" {
		br.Msg = "请输入分类名称"
		br.IsSendEmail = false
		return
	}
	if req.ParentId < 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	count, err := ai_summary.GetAiSummaryClassifyCount(req.ClassifyName, req.ParentId)
	if err != nil {
		br.Msg = "判断名称是否已存在失败"
		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
		return
	}
	if count > 0 {
		br.Msg = "分类名称已存在,请重新输入"
		br.IsSendEmail = false
		return
	}
	//获取该层级下最大的排序数
	maxSort, err := ai_summary.GetAiSummaryClassifyMaxSort(req.ParentId)

	classify := new(ai_summary.AiSummaryClassify)
	classify.ParentId = req.ParentId
	classify.ClassifyName = req.ClassifyName
	classify.HasData = 0
	classify.CreateTime = time.Now()
	classify.ModifyTime = time.Now()
	classify.SysUserId = this.SysUser.AdminId
	classify.SysUserRealName = this.SysUser.RealName
	classify.Level = req.Level + 1
	classify.Sort = maxSort + 1

	_, err = ai_summary.AddAiSummaryClassify(classify)
	if err != nil {
		br.Msg = "保存分类失败"
		br.ErrMsg = "保存分类失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Msg = "保存成功"
	br.Success = true
}

// @Title 修改ai纪要分类
// @Description 修改ai纪要分类接口
// @Param	request	body data_manage.EditChartClassifyReq true "type json string"
// @Success 200 Ret=200 修改成功
// @router /summary/classify/edit [post]
func (this *AiController) EditAiSummaryClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req ai_summary.EditAiSummaryClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.ClassifyName == "" {
		br.Msg = "请输入分类名称"
		br.IsSendEmail = false
		return
	}

	if req.AiSummaryClassifyId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	err = ai_summary.EditSandboxClassify(req.AiSummaryClassifyId, req.ClassifyName)
	if err != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存失败,Err:" + err.Error()
		return
	}

	br.Ret = 200
	br.Msg = "保存成功"
	br.Success = true
	br.IsAddLog = true
}

// @Title 删除纪要分类检测接口
// @Description 删除纪要分类检测接口
// @Param	request	body data_manage.ChartClassifyDeleteCheckResp true "type json string"
// @Success 200 Ret=200 检测成功
// @router /summary/classify/delete/check [post]
func (this *AiController) DeleteSandboxClassifyCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req ai_summary.AiSummaryClassifyDeleteCheckReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.AiSummaryClassifyId < 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}
	var deleteStatus int
	var tipsMsg string
	//删除分类
	if req.AiSummaryClassifyId > 0 {
		//判断分类下,是否含有纪要
		count, err := ai_summary.GetAiSummaryInfoCountByClassifyId(req.AiSummaryClassifyId)
		if err != nil {
			br.Msg = "删除失败"
			br.ErrMsg = "分类下是否含有指标失败,Err:" + err.Error()
			return
		}

		if count > 0 {
			deleteStatus = 1
			tipsMsg = "该分类下关联沙盘不可删除"
		}
	}

	if deleteStatus != 1 {
		classifyCount, err := ai_summary.GetAiSummaryInfoCountByClassifyId(req.AiSummaryClassifyId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "删除失败"
			br.ErrMsg = "分类下是否含有沙盘失败,Err:" + err.Error()
			return
		}
		if classifyCount > 0 {
			deleteStatus = 2
			tipsMsg = "确认删除当前目录及包含的子目录吗"
		}
	}
	if deleteStatus == 0 {
		tipsMsg = "可删除,进行删除操作"
	}

	resp := new(sandbox.SandboxClassifyDeleteCheckResp)
	resp.DeleteStatus = deleteStatus
	resp.TipsMsg = tipsMsg
	br.Ret = 200
	br.Msg = "检测成功"
	br.Success = true
	br.Data = resp
}

// @Title 删除纪要分类/纪要
// @Description 删除纪要分类/纪要接口
// @Param	request	body data_manage.DeleteChartClassifyReq true "type json string"
// @Success 200 Ret=200 删除成功
// @router /summary/classify/delete [post]
func (this *AiController) DeleteAiSummaryClassify() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req ai_summary.DeleteAiSummaryClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.AiSummaryClassifyId < 0 && req.AiSummaryId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}

	//删除分类
	if req.AiSummaryClassifyId > 0 && req.AiSummaryId == 0 {
		//判断是否含有纪要
		count, err := ai_summary.GetAiSummaryInfoCountByClassifyId(req.AiSummaryClassifyId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "删除失败"
			br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
			return
		}

		if count > 0 {
			br.Msg = "该目录下存在纪要,不可删除"
			br.IsSendEmail = false
			return
		}

		err = ai_summary.DeleteAiSummaryClassify(req.AiSummaryClassifyId)
		if err != nil {
			br.Msg = "删除失败"
			br.ErrMsg = "删除失败,Err:" + err.Error()
			return
		}
	}

	//删除纪要
	if req.AiSummaryId > 0 {
		summaryInfo, err := ai_summary.GetAiSummaryById(req.AiSummaryId)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				br.Msg = "纪要已删除,请刷新页面"
				br.ErrMsg = "指标不存在,Err:" + err.Error()
				return
			} else {
				br.Msg = "删除失败"
				br.ErrMsg = "删除失败,获取指标信息失败,Err:" + err.Error()
				return
			}
		}
		if summaryInfo == nil {
			br.Msg = "纪要已删除,请刷新页面"
			return
		}
		if summaryInfo.SysUserId != sysUser.AdminId {
			br.Msg = "仅纪要创建人可以删除"
			return
		}
		err = ai_summary.DelAiSummaryById(req.AiSummaryId)
		if err != nil {
			br.Msg = err.Error()
			return
		}
	}
	br.Ret = 200
	br.Msg = "删除成功"
	br.Success = true
	br.IsAddLog = true
}

// AiSummaryClassifyMove
// @Title 纪要分类移动接口
// @Description 纪要分类移动接口
// @Success 200 {object} data_manage.MoveChartClassifyReq
// @router /summary/classify/move [post]
func (this *AiController) AiSummaryClassifyMove() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req ai_summary.MoveAiSummaryClassifyReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}

	if req.AiSummaryClassifyId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "分类id小于等于0"
		return
	}
	//判断分类是否存在
	aiSummaryClassifyInfo, err := ai_summary.GetAiSummaryClassifyById(req.AiSummaryClassifyId)
	if err != nil {
		br.Msg = "移动失败"
		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
		return
	}

	updateCol := make([]string, 0)

	// 判断移动的是分类还是沙盘
	if req.AiSummaryId > 0 {
		//判断分类是否存在
		count, _ := ai_summary.GetAiSummaryClassifyCountById(req.AiSummaryClassifyId)
		if count <= 0 {
			br.Msg = "分类已被删除,不可移动,请刷新页面"
			return
		}

		aiSummaryInfo, err := ai_summary.GetAiSummaryById(req.AiSummaryId)
		if err != nil {
			br.Msg = "移动失败"
			br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
			return
		}

		//如果改变了分类,那么移动该图表数据
		// 11/22 ETA逻辑优化去除名称重复限制
		if aiSummaryInfo.ClassifyId != req.ParentClassifyId {
			////查询需要修改的分类下是否存在同一个图表名称
			//tmpSandboxInfo, tmpErr := sandbox.GetSandboxByClassifyIdAndName(req.ParentClassifyId, aiSummaryInfo.Name)
			//if tmpErr != nil && tmpErr.Error() != utils.ErrNoRow() {
			//	br.Msg = "移动失败"
			//	br.ErrMsg = "移动失败,Err:" + tmpErr.Error()
			//	return
			//}
			//if tmpSandboxInfo != nil {
			//	br.Msg = "移动失败,同一个分类下沙盘名称不允许重复"
			//	br.ErrMsg = "移动失败,同一个分类下沙盘名称不允许重复"
			//	return
			//}
			err = ai_summary.MoveAiSummary(req.AiSummaryId, req.ParentClassifyId)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "移动失败,Err:" + err.Error()
				return
			}
		}

		//移动排序
		updateCol := make([]string, 0)
		//如果有传入 上一个兄弟节点分类id
		if req.PrevId > 0 {
			if req.PrevType == 1 {
				//上一个兄弟节点
				prevClassify, err := ai_summary.GetAiSummaryClassifyById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是分类 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := ai_summary.GetAiSummaryClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
						if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, prevClassify.AiSummaryClassifyId, prevClassify.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
							if nextClassify.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					} else {
						//上一个节点是分类 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := ai_summary.GetAiSummaryById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(分类)与下一个兄弟(沙盘)的排序权重是一致的,那么需要将下一个兄弟(沙盘)(以及下个兄弟(沙盘)的同样排序权重)的排序权重+2,自己变成上一个兄弟(分类)的排序权重+1
						if prevClassify.Sort == nextChartInfo.Sort || prevClassify.Sort == aiSummaryInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, prevClassify.AiSummaryClassifyId, prevClassify.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟(沙盘)的排序权重正好是上个兄弟节点(分类)的下一层,那么需要再加一层了
							if nextChartInfo.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.AiSummaryClassifyId, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					}

				}

				aiSummaryInfo.Sort = prevClassify.Sort + 1
				aiSummaryInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			} else {
				prevAiSumary, err := ai_summary.GetAiSummaryById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是沙盘 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := ai_summary.GetAiSummaryClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的,那么需要将下一个兄弟(分类)(以及下个兄弟(分类)的同样排序权重)的排序权重+2,自己变成上一个兄弟(沙盘)的排序权重+1
						if prevAiSumary.Sort == nextClassify.Sort || prevAiSumary.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层,那么需要再加一层了
							if nextClassify.Sort-prevAiSumary.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
							}
						}
					} else {
						//上一个节点是沙盘 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := ai_summary.GetAiSummaryById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的,那么需要将下一个兄弟(分类)(以及下个兄弟(分类)的同样排序权重)的排序权重+2,自己变成上一个兄弟(沙盘)的排序权重+1
						if prevAiSumary.Sort == nextChartInfo.Sort || prevAiSumary.Sort == aiSummaryInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层,那么需要再加一层了
							if nextChartInfo.Sort-prevAiSumary.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
							}
						}
					}

				}

				aiSummaryInfo.Sort = prevAiSumary.Sort + 1
				aiSummaryInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")
			}

		} else {
			// prevId为0,也就是沙盘移到最前端
			firstClassify, err := ai_summary.GetFirstAiSummaryByClassifyId(req.AiSummaryClassifyId)
			if err != nil && err.Error() != utils.ErrNoRow() {
				br.Msg = "移动失败"
				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
				return
			}

			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
			if firstClassify != nil && firstClassify.Sort == 0 {
				updateSortStr := ` sort + 1 `
				_ = ai_summary.UpdateAiSummarySortByClassifyId(firstClassify.ClassifyId, 0, firstClassify.AiSummaryId-1, updateSortStr)
			}

			aiSummaryInfo.Sort = 0 //那就是排在第一位
			aiSummaryInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "Sort", "ModifyTime")

		}

		//更新
		if len(updateCol) > 0 {
			err = aiSummaryInfo.Update(updateCol)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "修改失败,Err:" + err.Error()
				return
			}
		}
	} else {
		//移动的是分类
		//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
		if aiSummaryClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId != 0 {
			parentChartClassifyInfo, err := ai_summary.GetAiSummaryClassifyById(req.ParentClassifyId)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "获取上级分类信息失败,Err:" + err.Error()
				return
			}
			aiSummaryClassifyInfo.ParentId = parentChartClassifyInfo.AiSummaryClassifyId
			aiSummaryClassifyInfo.Level = parentChartClassifyInfo.Level + 1
			aiSummaryClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
		} else if aiSummaryClassifyInfo.ParentId != req.ParentClassifyId && req.ParentClassifyId == 0 {
			//改为一级分类
			aiSummaryClassifyInfo.ParentId = req.ParentClassifyId
			aiSummaryClassifyInfo.Level = 1
			aiSummaryClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "ParentId", "Level", "ModifyTime")
		}

		//如果有传入 上一个兄弟节点分类id
		if req.PrevId > 0 {
			if req.PrevType == 1 {
				//上一个节点是分类
				//上一个兄弟节点
				prevClassify, err := ai_summary.GetAiSummaryClassifyById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是分类 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := ai_summary.GetAiSummaryClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
						if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, prevClassify.AiSummaryClassifyId, prevClassify.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
							if nextClassify.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					} else {
						//上一个节点是分类 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := ai_summary.GetAiSummaryById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(分类)与下一个兄弟(沙盘)的排序权重是一致的,那么需要将下一个兄弟(沙盘)(以及下个兄弟(沙盘)的同样排序权重)的排序权重+2,自己变成上一个兄弟(分类)的排序权重+1
						if prevClassify.Sort == nextChartInfo.Sort || prevClassify.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, prevClassify.AiSummaryClassifyId, prevClassify.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
						} else {
							//如果下一个兄弟(沙盘)的排序权重正好是上个兄弟节点(分类)的下一层,那么需要再加一层了
							if nextChartInfo.Sort-prevClassify.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.AiSummaryClassifyId, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevClassify.AiSummaryClassifyId, prevClassify.Sort, 0, updateSortStr)
							}
						}
					}

				}

				aiSummaryClassifyInfo.Sort = prevClassify.Sort + 1
				aiSummaryClassifyInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			} else {
				//上一个节点是沙盘
				prevAiSumary, err := ai_summary.GetAiSummaryById(req.PrevId)
				if err != nil {
					br.Msg = "移动失败"
					br.ErrMsg = "获取上一个兄弟节点分类信息失败,Err:" + err.Error()
					return
				}

				//如果是移动在两个兄弟节点之间
				if req.NextId > 0 {
					if req.NextType == 1 {
						//上一个节点是沙盘 下一个节点是分类的情况
						//下一个兄弟节点
						nextClassify, err := ai_summary.GetAiSummaryClassifyById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的,那么需要将下一个兄弟(分类)(以及下个兄弟(分类)的同样排序权重)的排序权重+2,自己变成上一个兄弟(沙盘)的排序权重+1
						if prevAiSumary.Sort == nextClassify.Sort || prevAiSumary.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层,那么需要再加一层了
							if nextClassify.Sort-prevAiSumary.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
							}
						}
					} else {
						//上一个节点是沙盘 下一个节点是沙盘的情况
						//下一个兄弟节点
						nextChartInfo, err := ai_summary.GetAiSummaryById(req.NextId)
						if err != nil {
							br.Msg = "移动失败"
							br.ErrMsg = "获取下一个兄弟节点分类信息失败,Err:" + err.Error()
							return
						}
						//如果上一个兄弟(沙盘)与下一个兄弟(分类)的排序权重是一致的,那么需要将下一个兄弟(分类)(以及下个兄弟(分类)的同样排序权重)的排序权重+2,自己变成上一个兄弟(沙盘)的排序权重+1
						if prevAiSumary.Sort == nextChartInfo.Sort || prevAiSumary.Sort == aiSummaryClassifyInfo.Sort {
							//变更兄弟节点的排序
							updateSortStr := `sort + 2`
							_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
							_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
						} else {
							//如果下一个兄弟(分类)的排序权重正好是上个兄弟(沙盘)节点的下一层,那么需要再加一层了
							if nextChartInfo.Sort-prevAiSumary.Sort == 1 {
								//变更兄弟节点的排序
								updateSortStr := `sort + 1`
								_ = ai_summary.UpdateAiSummaryClassifySortByParentId(prevAiSumary.ClassifyId, 0, prevAiSumary.Sort, updateSortStr)
								_ = ai_summary.UpdateAiSummarySortByClassifyId(prevAiSumary.ClassifyId, prevAiSumary.Sort, prevAiSumary.AiSummaryId, updateSortStr)
							}
						}
					}

				}
				aiSummaryClassifyInfo.Sort = prevAiSumary.Sort + 1
				aiSummaryClassifyInfo.ModifyTime = time.Now()
				updateCol = append(updateCol, "Sort", "ModifyTime")

			}

		} else {
			firstClassify, err := ai_summary.GetFirstAiSummaryClassifyByParentId(aiSummaryClassifyInfo.ParentId)
			if err != nil && err.Error() != utils.ErrNoRow() {
				br.Msg = "移动失败"
				br.ErrMsg = "获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error()
				return
			}

			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
			if firstClassify != nil && firstClassify.Sort == 0 {
				updateSortStr := ` sort + 1 `
				_ = ai_summary.UpdateAiSummaryClassifySortByParentId(firstClassify.ParentId, firstClassify.AiSummaryClassifyId-1, 0, updateSortStr)
			}

			aiSummaryClassifyInfo.Sort = 0 //那就是排在第一位
			aiSummaryClassifyInfo.ModifyTime = time.Now()
			updateCol = append(updateCol, "Sort", "ModifyTime")
		}

		//更新
		if len(updateCol) > 0 {
			err = aiSummaryClassifyInfo.Update(updateCol)
			if err != nil {
				br.Msg = "移动失败"
				br.ErrMsg = "修改失败,Err:" + err.Error()
				return
			}
		}
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "移动成功"
}

// @Title Ai纪要列表接口
// @Description Ai纪要列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
// @Param   AiSummaryClassifyId   query   int  true       "分类id"
// @Param   KeyWord   query   string  true       "搜索关键词"
// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
// @Success 200 {object} data_manage.ChartListResp
// @router /summary/list [get]
func (this *AiController) AiSummaryList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	aiSummaryClassifyId, _ := this.GetInt("AiSummaryClassifyId")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	keyWord := this.GetString("KeyWord")

	var total int
	page := paging.GetPaging(currentIndex, pageSize, total)

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	var condition string
	var pars []interface{}

	if aiSummaryClassifyId > 0 {
		sandboxClassifyIds, err := ai_summary.GetAiSummaryClassify(aiSummaryClassifyId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "获取图表信息失败"
			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
			return
		}
		condition += " AND ai_summary_classify_id IN(" + sandboxClassifyIds + ") "
		//pars = append(pars, chartClassifyId)
	}
	if keyWord != "" {
		condition += ` AND  ( title LIKE '%` + keyWord + `%' )`
	}

	//只看我的
	isShowMe, _ := this.GetBool("IsShowMe")
	if isShowMe {
		condition += ` AND sys_user_id = ? `
		pars = append(pars, sysUser.AdminId)
	}

	//获取图表信息
	list, err := ai_summary.GetAiSummaryListByCondition(condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取纪要信息失败"
		br.ErrMsg = "获取纪要信息失败,Err:" + err.Error()
		return
	}

	for i, v := range list {
		ids, err := ai_summary.GetAiSummaryAllParentByClassifyId(v.ClassifyId)
		if err != nil {
			br.Msg = "获取父级信息错误!"
			br.ErrMsg = "获取父级信息错误,Err:" + err.Error()
			return
		}
		list[i].ParentIds = ids
	}
	resp := new(ai_summary.AiSummaryListResp)
	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
		items := make([]*ai_summary.AiSummaryItems, 0)
		resp.Paging = page
		resp.List = items
		br.Ret = 200
		br.Success = true
		br.Msg = "获取成功"
		return
	}

	dataCount, err := ai_summary.GetAiSummaryListCountByCondition(condition, pars)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
		return
	}
	page = paging.GetPaging(currentIndex, pageSize, dataCount)
	resp.Paging = page
	resp.List = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// @Title Ai纪要详情接口
// @Description Ai纪要详情接口
// @Param   AiSummaryId   query   int  true       "详情id"
// @Success 200 {object} data_manage.ChartListResp
// @router /summary/detail [get]
func (this *AiController) AiSummaryDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	aiSummaryId, _ := this.GetInt("AiSummaryId")

	detail, err := ai_summary.GetAiSummaryItemById(aiSummaryId)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Success = true
		br.Msg = "获取沙盘信息失败"
		br.ErrMsg = "获取沙盘信息失败,Err:" + err.Error()
		return
	}
	resp := ai_summary.AiSummaryDetailResp{
		AiSummaryItems: detail,
	}

	if detail.SaDocId > 0 {
		item := new(saModel.SaDoc)
		e := item.GetItemById(detail.SaDocId)
		if e != nil {
			if e.Error() == utils.ErrNoRow() {
				br.Msg = "文档已被删除, 请刷新页面"
				return
			}
			br.Msg = "获取失败"
			br.ErrMsg = "获取文档信息失败, Err: " + e.Error()
			return
		}
		resp.SaDocTitle = item.Title
		resp.SaDocClassifyId = item.ClassifyId
	}

	br.Data = resp
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// @Title 新增ai纪要
// @Description 新增ai纪要接口
// @Param	request	body data_manage.AddChartClassifyReq true "type json string"
// @Success 200 Ret=200 保存成功
// @router /summary/add [post]
func (this *AiController) AddAiSummary() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req ai_summary.AddAiSummaryReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.Title == "" {
		br.Msg = "请输入名称"
		br.IsSendEmail = false
		return
	}
	if req.SummaryContent == "" {
		br.Msg = "纪要内容为空"
		br.IsSendEmail = false
		return
	}
	if req.ClassifyId < 0 {
		br.Msg = "分类id错误"
		br.IsSendEmail = false
		return
	}
	//获取该层级下最大的排序数
	maxSort, err := ai_summary.GetAiSummaryMaxSort(req.ClassifyId)

	summary := &ai_summary.AiSummary{
		SaDocId:         req.SaDocId,
		OriginContent:   req.OriginContent,
		SummaryContent:  req.SummaryContent,
		ClassifyId:      req.ClassifyId,
		SysUserId:       this.SysUser.AdminId,
		SysUserRealName: this.SysUser.RealName,
		Title:           req.Title,
		CreateTime:      time.Now(),
		ModifyTime:      time.Now(),
		OpenaiFileName:  req.OpenaiFileName,
		OpenaiFilePath:  req.OpenaiFilePath,
		OriginTitle:     req.OriginTitle,
		Sort:            maxSort + 1,
	}

	id, err := ai_summary.AddAiSummary(summary)
	if err != nil {
		br.Msg = "保存分类失败"
		br.ErrMsg = "保存分类失败,Err:" + err.Error()
		return
	}
	classify, err := ai_summary.GetAiSummaryClassifyById(req.ClassifyId)
	if err != nil {
		br.Msg = "获取分类信息失败"
		br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
		return
	}

	resp := ai_summary.AiSummaryAddResp{
		AiSummaryId: int(id),
		UniqueCode:  strconv.Itoa(req.ClassifyId) + "_" + strconv.Itoa(int(id)),
		ParentId:    classify.ParentId,
	}

	br.Ret = 200
	br.Msg = "保存成功"
	br.Success = true
	br.Data = resp
}

// @Title 生成ai纪要
// @Description 生成ai纪要接口
// @Param	request	body data_manage.AddChartClassifyReq true "type json string"
// @Success 200 Ret=200 保存成功
// @router /summary/generate [post]
func (this *AiController) GenerateAiSummary() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	var req ai_summary.GenerateAiSummaryReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + err.Error()
		return
	}
	if req.Prompt == "" {
		br.Msg = "请输入提示词"
		br.IsSendEmail = false
		return
	}
	if req.OriginContent == "" && len(req.OpenaiFileId) == 0 && req.SaDocId <= 0 {
		br.Msg = "参数错误"
		br.IsSendEmail = false
		return
	}
	if req.SaDocId > 0 {
		// 获取段落
		sectionOB := new(saModel.SaDocSection)
		sectionCond := fmt.Sprintf(` AND %s = ?`, saModel.SaDocSectionColumns.DocId)
		sectionPars := make([]interface{}, 0)
		sectionPars = append(sectionPars, req.SaDocId)
		sectionList, e := sectionOB.GetItemsByCondition(sectionCond, sectionPars, []string{}, "")
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取段落信息失败, Err: " + e.Error()
			return
		}
		secIds := make([]int, 0)
		for _, s := range sectionList {
			secIds = append(secIds, s.SaDocSectionId)
		}

		for _, v := range sectionList {
			req.OriginContent += v.Content + "<br>"
		}
	}

	if utils.Re == nil {
		key := "CACHE_CHAT_" + strconv.Itoa(this.SysUser.AdminId)
		cacheVal, err := utils.Rc.RedisInt(key)
		fmt.Println("RedisString:", cacheVal, "err:", err)
		if err != nil && (err.Error() != "redigo: nil returned" && err.Error() != "redis: nil") {
			br.Msg = "获取数据失败!"
			br.ErrMsg = "获取数据失败,Err:" + err.Error()
			return
		}
		putVal := 0
		if cacheVal <= 0 {
			putVal = utils.AiChatLimit
		} else {
			putVal = cacheVal - 1
		}

		if putVal <= 0 {
			br.Msg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!"
			br.ErrMsg = "您今日" + strconv.Itoa(utils.AiChatLimit) + "次问答已达上限,请明天再来!"
			return
		}
		lastSecond := utils.GetTodayLastSecond()
		utils.Rc.Put(key, putVal, lastSecond)
	}

	resp := new(aimod.ChatResp)

	if req.OriginContent != "" {
		// 直接提问的方式

		//根据提问,获取信息
		ask := req.Prompt + req.OriginContent

		var answer string
		//answerArr := []string{
		//	"周度数据显示,成品油现货市场价格跟随原油下跌,但近期相对抗跌,裂解价差走扩。批零价差方面汽油收窄,柴油走扩",
		//	"出口利润在原油下跌海外成品油矛盾更大的情况下汽柴油出口窗口完全关闭",
		//	"汽油需求在经历五一假期的一段高峰后将回归平稳,总体没有明显矛盾,后期我们担心更多的还是柴油。"}
		//获取主题下的所有信息
		//AiChatTopicId

		//获取主题下的所有信息
		//AiChatTopicId
		historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "获取主题历史数据失败!"
			br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
			return
		}

		historyChatList := make([]aimod.HistoryChat, 0)
		for _, v := range historyList {
			historyChat := new(aimod.HistoryChat)
			historyChat.Ask = v.Ask
			historyChat.Answer = v.Answer
			historyChatList = append(historyChatList, *historyChat)
		}

		answer, err = aiser.ChatAutoMsg(ask, historyChatList, req.Model)
		if err != nil {
			br.Msg = "获取数据失败!"
			br.ErrMsg = "获取数据失败,ChatAutoMsg,Err:" + err.Error()
			return
		}

		resp.Ask = ask
		resp.Answer = answer
		resp.Model = req.Model

		if req.AiChatTopicId <= 0 { //新增
			topic := new(aimod.AiChatTopic)
			topic.TopicName = ask
			topic.SysUserId = this.SysUser.AdminId
			topic.SysUserRealName = this.SysUser.RealName
			topic.CreateTime = time.Now()
			topic.ModifyTime = time.Now()
			topicId, err := aimod.AddAiChatTopic(topic)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题失败,Err:" + err.Error()
				return
			}
			resp.AiChatTopicId = int(topicId)
			chatItem := new(aimod.AiChat)
			chatItem.AiChatTopicId = resp.AiChatTopicId
			chatItem.Ask = ask
			chatItem.AskUuid = utils.MD5(ask)
			chatItem.Answer = answer
			chatItem.Model = EnabledModelsForMap[req.Model]
			chatItem.SysUserId = this.SysUser.AdminId
			chatItem.SysUserRealName = this.SysUser.RealName
			chatItem.CreateTime = time.Now()
			chatItem.ModifyTime = time.Now()
			_, err = aimod.AddAiChat(chatItem)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
				return
			}
		} else {
			resp.AiChatTopicId = req.AiChatTopicId
			chatItem := new(aimod.AiChat)
			chatItem.AiChatTopicId = resp.AiChatTopicId
			chatItem.Ask = ask
			chatItem.AskUuid = utils.MD5(ask)
			chatItem.Answer = answer
			chatItem.Model = EnabledModelsForMap[req.Model]
			chatItem.SysUserId = this.SysUser.AdminId
			chatItem.SysUserRealName = this.SysUser.RealName
			chatItem.CreateTime = time.Now()
			chatItem.ModifyTime = time.Now()
			_, err = aimod.AddAiChat(chatItem)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
				return
			}
		}

	} else if len(req.OpenaiFileId) > 0 {
		// 走文件上传的方式
		//根据提问,获取信息

		ask := req.Prompt
		askUuid := utils.MD5(ask)

		var assistantId, threadId string
		if req.AiChatTopicId > 0 {
			aiChatTopicObj := new(aimod.AiChatTopic)
			aiChatTopicObj.AiChatTopicId = req.AiChatTopicId
			topic, err := aiChatTopicObj.GetAiChatTopicById()
			if err != nil {
				if err.Error() == utils.ErrNoRow() {
					br.Msg = "获取数据失败!"
					br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
					return
				}
				br.Msg = "获取数据失败!"
				br.ErrMsg = "获取数据失败,GetAiChatTopicById,Err:" + err.Error()
				return
			}
			assistantId = topic.AssistantId
			threadId = topic.ThreadId
		}

		var answer string
		//获取主题下的所有信息
		//AiChatTopicId
		//historyList, err := aimod.GetAiChatList(req.AiChatTopicId)
		//if err != nil && err.Error() != utils.ErrNoRow() {
		//	br.Msg = "获取主题历史数据失败!"
		//	br.ErrMsg = "获取主题历史数据失败,Err:" + err.Error()
		//	return
		//}

		frList := make([]aimod.HistoryChat, 0)
		tmpFileIdList := make([]string, 0)
		tmpFileIdList = append(tmpFileIdList, req.OpenaiFileId...)
		//// 历史消息
		//for _, v := range historyList {
		//	if v.OpenaiFileId != "" {
		//		tmpFileIdList = append(tmpFileIdList, v.OpenaiFileId)
		//	} else {
		//		historyFr := new(aimod.HistoryChat)
		//		historyFr.Ask = v.Ask
		//		historyFr.Answer = v.Answer
		//		historyFr.OpenaiFileId = tmpFileIdList
		//		frList = append(frList, *historyFr)
		//		tmpFileIdList = []string{}
		//	}
		//}
		// 当前的消息
		{
			frItem := new(aimod.HistoryChat)
			frItem.Ask = ask
			frItem.Answer = ""
			frItem.OpenaiFileId = tmpFileIdList
			frList = append(frList, *frItem)
		}

		fileRetrieveResp, err := aiser.FileRetrieve(assistantId, threadId, req.Model, frList, req.OpenaiFileId)
		if err != nil {
			br.Msg = "获取数据失败!"
			br.ErrMsg = "获取数据失败,FileRetrieve,Err:" + err.Error()
			return
		}

		if fileRetrieveResp != nil {
			if fileRetrieveResp.Ret == 200 {
				assistantId = fileRetrieveResp.Data.AssistantId
				threadId = fileRetrieveResp.Data.ThreadId
				answer = fileRetrieveResp.Data.Answer
			} else {
				br.Msg = "获取数据失败!"
				br.ErrMsg = fileRetrieveResp.Msg
				return
			}
		}

		if req.AiChatTopicId <= 0 { //新增
			topic := new(aimod.AiChatTopic)
			topic.TopicName = ask
			topic.SysUserId = this.SysUser.AdminId
			topic.SysUserRealName = this.SysUser.RealName
			topic.CreateTime = time.Now()
			topic.ModifyTime = time.Now()
			topic.AssistantId = assistantId
			topic.ThreadId = threadId
			topicId, err := aimod.AddAiChatTopic(topic)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题失败,Err:" + err.Error()
				return
			}
			chatItem := new(aimod.AiChat)
			chatItem.AiChatTopicId = int(topicId)
			chatItem.Ask = ask
			chatItem.AskUuid = utils.MD5(ask)
			chatItem.Answer = answer
			chatItem.Model = EnabledModelsForMap[req.Model]
			chatItem.SysUserId = this.SysUser.AdminId
			chatItem.SysUserRealName = this.SysUser.RealName
			chatItem.CreateTime = time.Now()
			chatItem.ModifyTime = time.Now()
			_, err = aimod.AddAiChat(chatItem)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
				return
			}
			req.AiChatTopicId = int(topicId)
		} else {
			chatItem := new(aimod.AiChat)
			chatItem.AiChatTopicId = req.AiChatTopicId
			chatItem.Ask = ask
			chatItem.AskUuid = askUuid
			chatItem.Answer = answer
			chatItem.Model = EnabledModelsForMap[req.Model]
			chatItem.SysUserId = this.SysUser.AdminId
			chatItem.SysUserRealName = this.SysUser.RealName
			chatItem.CreateTime = time.Now()
			chatItem.ModifyTime = time.Now()
			_, err = aimod.AddAiChat(chatItem)
			if err != nil {
				br.Msg = "获取数据失败!"
				br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
				return
			}
			//更新	assistantId,threadId
			aiChatTopicObj := new(aimod.AiChatTopic)

			updateParams := make(map[string]interface{})
			updateParams["assistant_id"] = assistantId
			updateParams["thread_id"] = threadId
			updateParams["modify_time"] = time.Now()

			whereParam := make(map[string]interface{})
			whereParam["ai_chat_topic_id"] = req.AiChatTopicId

			err = aiChatTopicObj.Update(updateParams, whereParam)
			if err != nil {
				br.Msg = "获取失败!"
				br.ErrMsg = "修改助手标识失败,Err:" + err.Error()
				return
			}
		}
		resp.Model = aimod.ModelViewMap[req.Model]
		resp.AiChatTopicId = req.AiChatTopicId
		resp.Ask = ask
		resp.Answer = answer
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

//// @Title 文件上传
//// @Description 文件上传接口
//// @Param   File   query   file  true       "文件"
//// @Param   AiChatTopicId   query   int  true       "主题id"
//// @Success 200 {object} models.ResourceResp
//// @router /file/upload [post]
//func (this *AiFileController) FileUpload2() {
//	br := new(models.BaseResponse).Init()
//	defer func() {
//		this.Data["json"] = br
//		this.ServeJSON()
//	}()
//
//	f, h, err := this.GetFile("File")
//	if err != nil {
//		br.Msg = "获取资源信息失败"
//		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
//		return
//	}
//	model := this.GetString("Model")
//
//	aiChatTopicId, _ := this.GetInt("AiChatTopicId")
//
//	uploadFileName := h.Filename //上传的文件名
//	ext := path.Ext(h.Filename)
//	dateDir := time.Now().Format("20060102")
//	uploadDir := utils.STATIC_DIR + "ai/" + dateDir
//	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
//	if err != nil {
//		br.Msg = "存储目录创建失败"
//		br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
//		return
//	}
//	randStr := utils.GetRandStringNoSpecialChar(28)
//	fileName := randStr + ext
//	fpath := uploadDir + "/" + fileName
//	defer f.Close() //关闭上传文件
//	err = this.SaveToFile("File", fpath)
//	if err != nil {
//		br.Msg = "文件上传失败"
//		br.ErrMsg = "文件上传失败,Err:" + err.Error()
//		return
//	}
//	resourceUrl := ``
//	ossClient := services.NewOssClient()
//	if ossClient == nil {
//		br.Msg = "上传失败"
//		br.ErrMsg = "初始化OSS服务失败"
//		return
//	}
//	resourceUrl, err = ossClient.UploadFile(fileName, fpath, "")
//	if err != nil {
//		br.Msg = "文件上传失败"
//		br.ErrMsg = "文件上传失败,Err:" + err.Error()
//		return
//	}
//
//	defer func() {
//		os.Remove(fpath)
//	}()
//
//	item := new(models.Resource)
//	item.ResourceUrl = resourceUrl
//	item.ResourceType = 1
//	item.CreateTime = time.Now()
//	newId, err := models.AddResource(item)
//	if err != nil {
//		br.Msg = "资源上传失败"
//		br.ErrMsg = "资源上传失败,Err:" + err.Error()
//		return
//	}
//	//调用AI接口,上传文件
//	resp := models.ResourceResp{
//		Id:           newId,
//		ResourceUrl:  resourceUrl,
//		ResourceName: uploadFileName,
//	}
//	uploadResult, err := aiser.OpenAiFileUpload(resourceUrl, uploadFileName, model)
//	if err != nil {
//		br.Msg = "文件上传失败"
//		br.ErrMsg = "文件上传失败,Err:" + err.Error()
//		return
//	}
//
//	var assistantId, threadId string
//	if aiChatTopicId > 0 {
//		aiChatTopicObj := new(aimod.AiChatTopic)
//		aiChatTopicObj.AiChatTopicId = aiChatTopicId
//		topic, err := aiChatTopicObj.GetAiChatTopicById()
//		if err != nil {
//			if err.Error() == utils.ErrNoRow() {
//				br.Msg = "获取数据失败!"
//				br.ErrMsg = "获取数据失败,主题不存在,Err:" + err.Error()
//				return
//			}
//			br.Msg = "获取数据失败!"
//			br.ErrMsg = "获取数据失败,GetAiChatTopicById,Err:" + err.Error()
//			return
//		}
//		assistantId = topic.AssistantId
//		threadId = topic.ThreadId
//	}
//
//	if aiChatTopicId <= 0 { //新增
//		topic := new(aimod.AiChatTopic)
//		var filenameWithSuffix string
//		filenameWithSuffix = path.Base(uploadFileName)
//		var fileSuffix string
//		fileSuffix = path.Ext(filenameWithSuffix)
//		var filenameOnly string
//		filenameOnly = strings.TrimSuffix(filenameWithSuffix, fileSuffix)
//		topic.TopicName = filenameOnly
//		topic.SysUserId = this.SysUser.AdminId
//		topic.SysUserRealName = this.SysUser.RealName
//		topic.CreateTime = time.Now()
//		topic.ModifyTime = time.Now()
//		topic.AssistantId = assistantId
//		topic.ThreadId = threadId
//		topicId, err := aimod.AddAiChatTopic(topic)
//		if err != nil {
//			br.Msg = "获取数据失败!"
//			br.ErrMsg = "生成话题失败,Err:" + err.Error()
//			return
//		}
//		aiChatTopicId = int(topicId)
//		chatItem := new(aimod.AiChat)
//		chatItem.AiChatTopicId = aiChatTopicId
//		chatItem.Ask = uploadFileName
//		chatItem.AskUuid = utils.MD5(uploadFileName)
//		chatItem.Model = EnabledModelsForMap[model]
//		chatItem.SysUserId = this.SysUser.AdminId
//		chatItem.SysUserRealName = this.SysUser.RealName
//		if uploadResult != nil && uploadResult.Data != nil {
//			chatItem.OpenaiFileId = uploadResult.Data.ID
//			chatItem.OpenaiFileName = uploadFileName
//		}
//		chatItem.OpenaiFilePath = resourceUrl
//		chatItem.CreateTime = time.Now()
//		chatItem.ModifyTime = time.Now()
//		_, err = aimod.AddAiChat(chatItem)
//		if err != nil {
//			br.Msg = "获取数据失败!"
//			br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
//			return
//		}
//	} else {
//		chatItem := new(aimod.AiChat)
//		chatItem.AiChatTopicId = aiChatTopicId
//		chatItem.Ask = uploadFileName
//		chatItem.AskUuid = utils.MD5(fileName)
//		chatItem.Model = EnabledModelsForMap[model]
//		chatItem.SysUserId = this.SysUser.AdminId
//		chatItem.SysUserRealName = this.SysUser.RealName
//		if uploadResult != nil && uploadResult.Data != nil {
//			chatItem.OpenaiFileId = uploadResult.Data.ID
//			chatItem.OpenaiFileName = uploadFileName
//		}
//		chatItem.OpenaiFilePath = resourceUrl
//		chatItem.CreateTime = time.Now()
//		chatItem.ModifyTime = time.Now()
//		_, err = aimod.AddAiChat(chatItem)
//		if err != nil {
//			br.Msg = "获取数据失败!"
//			br.ErrMsg = "生成话题记录失败,Err:" + err.Error()
//			return
//		}
//	}
//
//	if uploadResult != nil && uploadResult.Data != nil && uploadResult.Data.ID != "" {
//		uploadObj := new(aimod.FileUploadRecord)
//		uploadObj.AdminId = this.SysUser.AdminId
//		uploadObj.FileUrl = resourceUrl
//		uploadObj.FileName = uploadFileName
//		uploadObj.OpenaiFileId = uploadResult.Data.ID
//		uploadObj.OpenaiFileName = uploadResult.Data.FileName
//		uploadObj.OpenaiObject = uploadResult.Data.Object
//		uploadObj.OpenaiStatus = uploadResult.Data.Status
//		uploadObj.OpenaiPurpose = uploadResult.Data.Purpose
//		uploadObj.OpenaiStatusDetails = uploadResult.Data.StatusDetails
//		uploadObj.OpenaiCreatedAt = uploadResult.Data.CreatedAt
//		uploadObj.CreateTime = time.Now()
//		uploadObj.ModifyTime = time.Now()
//		_, err = uploadObj.AddFileUploadRecord()
//		if err != nil {
//			br.Msg = "上传失败"
//			br.ErrMsg = "上传失败,Err:" + err.Error()
//			return
//		}
//		resp.OpenaiFileId = uploadObj.OpenaiFileId
//	}
//	resp.AiChatTopicId = aiChatTopicId
//	br.Msg = "上传成功"
//	br.Ret = 200
//	br.Success = true
//	br.Data = resp
//	return
//}

// AiSummaryClassifyList
// @Title 获取所有纪要分类接口-不包含沙盘
// @Description 获取所有纪要分类接口-不包含沙盘
// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
// @Success 200 {object} data_manage.ChartClassifyListResp
// @router /summary/classifyList [get]
func (this *AiController) AiSummaryClassifyList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	resp := new(ai_summary.AiSummaryClassifyListResp)

	rootList, err := ai_summary.GetAiSummaryClassifyByParentId(0)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}

	classifyAll, err := ai_summary.GetAiSummaryClassifyAll()
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}

	nodeAll := make([]*ai_summary.AiSummaryClassifyItems, 0)
	for k := range rootList {
		rootNode := rootList[k]
		aiSummaryService.AiSummaryClassifyItemsMakeTree(this.SysUser, classifyAll, rootNode)
		nodeAll = append(nodeAll, rootNode)
	}

	resp.AllNodes = nodeAll
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}