|
@@ -87,7 +87,7 @@ func (this *AiPredictModelIndexController) List() {
|
|
classifyIdName[v.AiPredictModelClassifyId] = v.ClassifyName
|
|
classifyIdName[v.AiPredictModelClassifyId] = v.ClassifyName
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ classifyIds := make([]int, 0)
|
|
// 筛选条件
|
|
// 筛选条件
|
|
highlightMap := make(map[int]string)
|
|
highlightMap := make(map[int]string)
|
|
indexOb := new(aiPredictModel.AiPredictModelIndex)
|
|
indexOb := new(aiPredictModel.AiPredictModelIndex)
|
|
@@ -99,8 +99,21 @@ func (this *AiPredictModelIndexController) List() {
|
|
pars = append(pars, indexId)
|
|
pars = append(pars, indexId)
|
|
}
|
|
}
|
|
if classifyId > 0 {
|
|
if classifyId > 0 {
|
|
- cond += fmt.Sprintf(" AND %s = ?", indexOb.Cols().ClassifyId)
|
|
|
|
- pars = append(pars, classifyId)
|
|
|
|
|
|
+ // 查询所有子分类
|
|
|
|
+ classifyInfo, err := aiPredictModel.GetAiPredictModelClassifyById(classifyId)
|
|
|
|
+ if err != nil && !utils.IsErrNoRow(err) {
|
|
|
|
+ br.Msg = "查询失败"
|
|
|
|
+ br.ErrMsg = "查询失败,Err:" + err.Error()
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ classifyIds, err = aiPredictModel.GetAiPredictModelClassifyChildIdsByLevelPath(classifyInfo.LevelPath)
|
|
|
|
+ if err != nil && !utils.IsErrNoRow(err) {
|
|
|
|
+ br.Msg = "查询失败"
|
|
|
|
+ br.ErrMsg = "查询子分类失败,Err:" + err.Error()
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ cond += fmt.Sprintf(" AND %s IN (%s)", indexOb.Cols().ClassifyId, utils.GetOrmInReplace(len(classifyIds)))
|
|
|
|
+ pars = append(pars, classifyIds)
|
|
}
|
|
}
|
|
//if keyword != "" {
|
|
//if keyword != "" {
|
|
// cond += fmt.Sprintf(" AND %s LIKE ?", indexOb.Cols().IndexName)
|
|
// cond += fmt.Sprintf(" AND %s LIKE ?", indexOb.Cols().IndexName)
|
|
@@ -109,7 +122,7 @@ func (this *AiPredictModelIndexController) List() {
|
|
|
|
|
|
// 有关键词从es中搜索
|
|
// 有关键词从es中搜索
|
|
if keyword != "" {
|
|
if keyword != "" {
|
|
- _, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_AI_PREDICT_MODEL, 0, []int{}, []int{}, []string{}, startSize, pageSize)
|
|
|
|
|
|
+ _, list, e := elastic.SearchDataSourceIndex(utils.EsDataSourceIndexName, keyword, utils.DATA_SOURCE_AI_PREDICT_MODEL, 0, classifyIds, []int{}, []string{}, startSize, pageSize)
|
|
if e != nil {
|
|
if e != nil {
|
|
br.Msg = "获取失败"
|
|
br.Msg = "获取失败"
|
|
br.ErrMsg = fmt.Sprintf("ES-搜索AI预测模型列表失败, %v", e)
|
|
br.ErrMsg = fmt.Sprintf("ES-搜索AI预测模型列表失败, %v", e)
|
|
@@ -216,20 +229,39 @@ func (this *AiPredictModelIndexController) Import() {
|
|
|
|
|
|
// 获取分类和用户,遍历时校验
|
|
// 获取分类和用户,遍历时校验
|
|
classifyNameId := make(map[string]int)
|
|
classifyNameId := make(map[string]int)
|
|
|
|
+ classifyMap := make(map[int]string)
|
|
adminNameId := make(map[string]int)
|
|
adminNameId := make(map[string]int)
|
|
{
|
|
{
|
|
classifyOb := new(aiPredictModel.AiPredictModelClassify)
|
|
classifyOb := new(aiPredictModel.AiPredictModelClassify)
|
|
- classifyCond := fmt.Sprintf(` AND %s = ?`, classifyOb.Cols().ParentId)
|
|
|
|
|
|
+ classifyCond := ``
|
|
classifyPars := make([]interface{}, 0)
|
|
classifyPars := make([]interface{}, 0)
|
|
- classifyPars = append(classifyPars, 0) // 只取一级分类(临时过渡方案,业务端只会加一级)
|
|
|
|
classifies, e := classifyOb.GetItemsByCondition(classifyCond, classifyPars, []string{}, "")
|
|
classifies, e := classifyOb.GetItemsByCondition(classifyCond, classifyPars, []string{}, "")
|
|
if e != nil {
|
|
if e != nil {
|
|
br.Msg = "导入失败"
|
|
br.Msg = "导入失败"
|
|
br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
|
|
br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // 构建完整的分类路径映射
|
|
|
|
+ for _, v := range classifies {
|
|
|
|
+ if this.Lang == utils.EnLangVersion {
|
|
|
|
+ classifyMap[v.AiPredictModelClassifyId] = v.ClassifyNameEn
|
|
|
|
+ } else {
|
|
|
|
+ classifyMap[v.AiPredictModelClassifyId] = v.ClassifyName
|
|
|
|
+ }
|
|
|
|
+ }
|
|
for _, v := range classifies {
|
|
for _, v := range classifies {
|
|
- classifyNameId[v.ClassifyName] = v.AiPredictModelClassifyId
|
|
|
|
|
|
+ levels := strings.Split(v.LevelPath, ",")
|
|
|
|
+ fullName := ""
|
|
|
|
+ for _, level := range levels {
|
|
|
|
+ if level == "" {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ cid, _ := strconv.Atoi(level)
|
|
|
|
+ fullName = fullName + "/" + classifyMap[cid]
|
|
|
|
+ }
|
|
|
|
+ fullName = strings.Trim(fullName, "/")
|
|
|
|
+ classifyNameId[fullName] = v.AiPredictModelClassifyId
|
|
}
|
|
}
|
|
|
|
|
|
admins, e := system.GetSysAdminList(``, make([]interface{}, 0), []string{}, "")
|
|
admins, e := system.GetSysAdminList(``, make([]interface{}, 0), []string{}, "")
|
|
@@ -285,10 +317,11 @@ func (this *AiPredictModelIndexController) Import() {
|
|
imports[indexName].Index.TrainStatus = `训练成功`
|
|
imports[indexName].Index.TrainStatus = `训练成功`
|
|
imports[indexName].Index.RunStatus = `运行成功`
|
|
imports[indexName].Index.RunStatus = `运行成功`
|
|
|
|
|
|
- // 分类
|
|
|
|
|
|
+ // 分类改成多级用斜杠/区分例如:一级/二级/三级/四级/五级/六级
|
|
classifyName := strings.TrimSpace(cells[1].String())
|
|
classifyName := strings.TrimSpace(cells[1].String())
|
|
if classifyNameId[classifyName] <= 0 {
|
|
if classifyNameId[classifyName] <= 0 {
|
|
br.Msg = fmt.Sprintf("分类:%s不存在", classifyName)
|
|
br.Msg = fmt.Sprintf("分类:%s不存在", classifyName)
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("分类:%s不存在,请先在系统中创建对应的分类", classifyName)
|
|
return
|
|
return
|
|
}
|
|
}
|
|
imports[indexName].Index.ClassifyId = classifyNameId[classifyName]
|
|
imports[indexName].Index.ClassifyId = classifyNameId[classifyName]
|
|
@@ -1462,3 +1495,252 @@ func getAllSearchDataSource(keyword string, source, subSource int) (list []*data
|
|
|
|
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// DownloadTemplate
|
|
|
|
+// @Title 下载导入模版
|
|
|
|
+// @Description 下载导入模版
|
|
|
|
+// @Success 200 {object} models.EdbdataClassifyResp
|
|
|
|
+// @Param Source query int false "来源:1:同花顺;2:wind;34:钢联"
|
|
|
|
+// @Param IsApi query int false "是否api:1:是;0:否"
|
|
|
|
+// @router /index/download_template [get]
|
|
|
|
+func (c *AiPredictModelIndexController) DownloadTemplate() {
|
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
|
+ defer func() {
|
|
|
|
+ c.Data["json"] = br
|
|
|
|
+ c.ServeJSON()
|
|
|
|
+ }()
|
|
|
|
+
|
|
|
|
+ c.Ctx.Output.Download("./static/template/AI预测模型导入模版.xlsx", "AI预测模型导入模版.xlsx")
|
|
|
|
+
|
|
|
|
+ br.Ret = 200
|
|
|
|
+ br.Success = true
|
|
|
|
+ br.Msg = "下载成功"
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Export
|
|
|
|
+// @Title 导出AI预测模型
|
|
|
|
+// @Description 导出AI预测模型
|
|
|
|
+// @Success 200 {object} models.EdbdataClassifyResp
|
|
|
|
+// @Param IndexId query int false "预测标的ID"
|
|
|
|
+// @router /index/export [get]
|
|
|
|
+func (c *AiPredictModelIndexController) Export() {
|
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
|
+ defer func() {
|
|
|
|
+ c.Data["json"] = br
|
|
|
|
+ c.ServeJSON()
|
|
|
|
+ }()
|
|
|
|
+
|
|
|
|
+ sysUser := c.SysUser
|
|
|
|
+ if sysUser == nil {
|
|
|
|
+ br.Msg = "请登录"
|
|
|
|
+ br.ErrMsg = "请登录,SysUser Is Empty"
|
|
|
|
+ br.Ret = 408
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ indexId, _ := c.GetInt("IndexId")
|
|
|
|
+ if indexId <= 0 {
|
|
|
|
+ br.Msg = "参数有误"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("参数有误, IndexId: %d", indexId)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取标的信息
|
|
|
|
+ indexOb := new(aiPredictModel.AiPredictModelIndex)
|
|
|
|
+ indexItem, e := indexOb.GetItemById(indexId)
|
|
|
|
+ if e != nil {
|
|
|
|
+ if utils.IsErrNoRow(e) {
|
|
|
|
+ br.Msg = "标的已被删除,请刷新页面"
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ br.Msg = "获取失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("获取标的失败, %v", e)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取分类名称
|
|
|
|
+ classifyOb := new(aiPredictModel.AiPredictModelClassify)
|
|
|
|
+ classifies, e := classifyOb.GetItemsByCondition("", make([]interface{}, 0), []string{}, "")
|
|
|
|
+ if e != nil {
|
|
|
|
+ br.Msg = "导出失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("获取分类失败, %v", e)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 构建分类ID到完整路径的映射
|
|
|
|
+ classifyIdToFullPath := make(map[int]string)
|
|
|
|
+ classifyMap := make(map[int]string)
|
|
|
|
+ for _, v := range classifies {
|
|
|
|
+ if c.Lang == utils.EnLangVersion {
|
|
|
|
+ classifyMap[v.AiPredictModelClassifyId] = v.ClassifyNameEn
|
|
|
|
+ } else {
|
|
|
|
+ classifyMap[v.AiPredictModelClassifyId] = v.ClassifyName
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, v := range classifies {
|
|
|
|
+ levels := strings.Split(v.LevelPath, ",")
|
|
|
|
+ fullPath := ""
|
|
|
|
+ for _, level := range levels {
|
|
|
|
+ if level == "" {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ cid, _ := strconv.Atoi(level)
|
|
|
|
+ if fullPath == "" {
|
|
|
|
+ fullPath = classifyMap[cid]
|
|
|
|
+ } else {
|
|
|
|
+ fullPath = fullPath + "/" + classifyMap[cid]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ classifyIdToFullPath[v.AiPredictModelClassifyId] = fullPath
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 获取标的数据
|
|
|
|
+ dataOb := new(aiPredictModel.AiPredictModelData)
|
|
|
|
+ dataCond := fmt.Sprintf(` AND %s = ?`, dataOb.Cols().IndexCode)
|
|
|
|
+ dataPars := make([]interface{}, 0)
|
|
|
|
+ dataPars = append(dataPars, indexItem.IndexCode)
|
|
|
|
+ dataList, e := dataOb.GetItemsByCondition(dataCond, dataPars, []string{}, fmt.Sprintf("%s DESC", dataOb.Cols().DataTime))
|
|
|
|
+ if e != nil {
|
|
|
|
+ br.Msg = "获取失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("获取标的数据失败, %v", e)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 创建Excel文件
|
|
|
|
+ xlFile := xlsx.NewFile()
|
|
|
|
+
|
|
|
|
+ // 创建预测标的列表页
|
|
|
|
+ sheet1, err := xlFile.AddSheet("列表页")
|
|
|
|
+ if err != nil {
|
|
|
|
+ br.Msg = "导出失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("创建Excel sheet失败, %v", err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加标题行
|
|
|
|
+ titleRow := sheet1.AddRow()
|
|
|
|
+ titles := []string{"预测标的", "分类", "模型类别", "创建人", "预测日期", "预测值", "预测频度", "方向准确率", "绝对偏差"}
|
|
|
|
+ for _, title := range titles {
|
|
|
|
+ cell := titleRow.AddCell()
|
|
|
|
+ cell.Value = title
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加数据行
|
|
|
|
+ dataRow := sheet1.AddRow()
|
|
|
|
+ dataRow.AddCell().Value = indexItem.IndexName
|
|
|
|
+ dataRow.AddCell().Value = classifyIdToFullPath[indexItem.ClassifyId]
|
|
|
|
+ dataRow.AddCell().Value = indexItem.ModelFramework
|
|
|
|
+ dataRow.AddCell().Value = indexItem.SysUserRealName
|
|
|
|
+ dataRow.AddCell().Value = indexItem.PredictDate.Format("2006-01-02")
|
|
|
|
+ dataRow.AddCell().Value = fmt.Sprintf("%.4f", indexItem.PredictValue)
|
|
|
|
+ dataRow.AddCell().Value = indexItem.PredictFrequency
|
|
|
|
+ dataRow.AddCell().Value = indexItem.DirectionAccuracy
|
|
|
|
+ dataRow.AddCell().Value = indexItem.AbsoluteDeviation
|
|
|
|
+
|
|
|
|
+ // 创建月度数据页
|
|
|
|
+ sheet2, err := xlFile.AddSheet("详情页")
|
|
|
|
+ if err != nil {
|
|
|
|
+ br.Msg = "导出失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("创建Excel sheet失败, %v", err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加标的名称行
|
|
|
|
+ nameRow := sheet2.AddRow()
|
|
|
|
+ nameCell := nameRow.AddCell()
|
|
|
|
+ nameCell.Value = indexItem.IndexName
|
|
|
|
+
|
|
|
|
+ // 添加标题行
|
|
|
|
+ titleRow2 := sheet2.AddRow()
|
|
|
|
+ titles2 := []string{"指标日期", "实际值", "预测值", "方向", "偏差率"}
|
|
|
|
+ for _, title := range titles2 {
|
|
|
|
+ cell := titleRow2.AddCell()
|
|
|
|
+ cell.Value = title
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加月度数据
|
|
|
|
+ monthlyData := make([]*aiPredictModel.AiPredictModelData, 0)
|
|
|
|
+ for _, data := range dataList {
|
|
|
|
+ if data.Source == aiPredictModel.ModelDataSourceMonthly {
|
|
|
|
+ monthlyData = append(monthlyData, data)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, data := range monthlyData {
|
|
|
|
+ dataRow := sheet2.AddRow()
|
|
|
|
+ dataRow.AddCell().Value = data.DataTime.Format("2006-01-02")
|
|
|
|
+ if data.Value.Valid {
|
|
|
|
+ dataRow.AddCell().Value = fmt.Sprintf("%.4f", data.Value.Float64)
|
|
|
|
+ } else {
|
|
|
|
+ dataRow.AddCell().Value = ""
|
|
|
|
+ }
|
|
|
|
+ if data.PredictValue.Valid {
|
|
|
|
+ dataRow.AddCell().Value = fmt.Sprintf("%.4f", data.PredictValue.Float64)
|
|
|
|
+ } else {
|
|
|
|
+ dataRow.AddCell().Value = ""
|
|
|
|
+ }
|
|
|
|
+ dataRow.AddCell().Value = data.Direction
|
|
|
|
+ dataRow.AddCell().Value = data.DeviationRate
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 创建日度数据页
|
|
|
|
+ sheet3, err := xlFile.AddSheet("日度数据表")
|
|
|
|
+ if err != nil {
|
|
|
|
+ br.Msg = "导出失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("创建Excel sheet失败, %v", err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加标的名称行
|
|
|
|
+ nameRow3 := sheet3.AddRow()
|
|
|
|
+ nameCell3 := nameRow3.AddCell()
|
|
|
|
+ nameCell3.Value = indexItem.IndexName
|
|
|
|
+
|
|
|
|
+ // 添加标题行
|
|
|
|
+ titleRow3 := sheet3.AddRow()
|
|
|
|
+ titles3 := []string{"日期", "实际值", "预测值"}
|
|
|
|
+ for _, title := range titles3 {
|
|
|
|
+ cell := titleRow3.AddCell()
|
|
|
|
+ cell.Value = title
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 添加日度数据
|
|
|
|
+ dailyData := make([]*aiPredictModel.AiPredictModelData, 0)
|
|
|
|
+ for _, data := range dataList {
|
|
|
|
+ if data.Source == aiPredictModel.ModelDataSourceDaily {
|
|
|
|
+ dailyData = append(dailyData, data)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for _, data := range dailyData {
|
|
|
|
+ dataRow := sheet3.AddRow()
|
|
|
|
+ dataRow.AddCell().Value = data.DataTime.Format("2006-01-02")
|
|
|
|
+ if data.Value.Valid {
|
|
|
|
+ dataRow.AddCell().Value = fmt.Sprintf("%.4f", data.Value.Float64)
|
|
|
|
+ } else {
|
|
|
|
+ dataRow.AddCell().Value = ""
|
|
|
|
+ }
|
|
|
|
+ if data.PredictValue.Valid {
|
|
|
|
+ dataRow.AddCell().Value = fmt.Sprintf("%.4f", data.PredictValue.Float64)
|
|
|
|
+ } else {
|
|
|
|
+ dataRow.AddCell().Value = ""
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 文件名称:预测标的名称+年月日
|
|
|
|
+ fileName := fmt.Sprintf("%s_%s.xlsx", indexItem.IndexName, time.Now().Format(utils.FormatDateShortUnSpace))
|
|
|
|
+ filePath := "./static/" + fileName
|
|
|
|
+
|
|
|
|
+ // 保存Excel文件
|
|
|
|
+ if err := xlFile.Save(filePath); err != nil {
|
|
|
|
+ br.Msg = "导出失败"
|
|
|
|
+ br.ErrMsg = fmt.Sprintf("保存Excel文件失败, %v", err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 下载文件
|
|
|
|
+ defer os.Remove(filePath)
|
|
|
|
+ c.Ctx.Output.Download(filePath, fileName)
|
|
|
|
+
|
|
|
|
+ br.Ret = 200
|
|
|
|
+ br.Success = true
|
|
|
|
+ br.Msg = "导出成功"
|
|
|
|
+}
|