package data_manage

import (
	"encoding/json"
	"eta/eta_api/controllers"
	"eta/eta_api/models"
	"eta/eta_api/models/data_manage"
	"eta/eta_api/models/data_manage/request"
	"eta/eta_api/services/data"
	correlationServ "eta/eta_api/services/data/correlation"
	"eta/eta_api/utils"
	"fmt"
	"strconv"
	"strings"
	"time"
)

// FactorEdbSeriesController 因子指标系列
type FactorEdbSeriesController struct {
	controllers.BaseAuthController
}

// CalculateFuncList
// @Title 计算方式列表
// @Description 计算方式列表
// @Param   EdbInfoType  query  int  false "指标计算类型: 0-普通指标; 1-预测指标"
// @Success Ret=200 操作成功
// @router /factor_edb_series/calculate_func/list [get]
func (this *FactorEdbSeriesController) CalculateFuncList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	edbInfoType, _ := this.GetInt("EdbInfoType", 0)

	funcOb := new(data_manage.FactorEdbSeriesCalculateFunc)
	cond := fmt.Sprintf(` AND %s = ?`, funcOb.Cols().EdbInfoType)
	pars := make([]interface{}, 0)
	pars = append(pars, edbInfoType)
	list, e := funcOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", funcOb.Cols().PrimaryId))
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = fmt.Sprintf("获取计算方式列表失败, Err: %v", e)
		return
	}
	resp := make([]*data_manage.FactorEdbSeriesCalculateFuncItem, 0)
	for _, v := range list {
		resp = append(resp, v.Format2Item())
	}

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

// Add
// @Title 新增
// @Description 新增
// @Param	request	body request.AddFactorEdbSeriesReq true "type json string"
// @Success Ret=200 操作成功
// @router /factor_edb_series/add [post]
func (this *FactorEdbSeriesController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		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 request.AddFactorEdbSeriesReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
		return
	}
	req.SeriesName = strings.TrimSpace(req.SeriesName)
	if req.SeriesName == "" {
		br.Msg = "请输入指标系列名称"
		return
	}
	if len(req.EdbInfoIds) <= 0 {
		br.Msg = "请选择因子指标系列"
		return
	}
	if len(req.EdbInfoIds) > 100 {
		br.Msg = "添加指标总数量不得超过100"
		return
	}
	calculateLen := len(req.Calculates)
	if calculateLen > 5 {
		br.Msg = "计算公式不可超过5个"
		return
	}
	var calculatesJson string
	if calculateLen > 0 {
		b, e := json.Marshal(req.Calculates)
		if e != nil {
			br.Msg = "计算方式格式有误"
			br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
			return
		}
		calculatesJson = string(b)
		for _, v := range req.Calculates {
			switch v.Source {
			case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
				if v.Formula == nil {
					br.Msg = "请输入N值"
					return
				}
				formula, ok := v.Formula.(string)
				if !ok {
					br.Msg = "N值格式有误"
					return
				}
				formulaInt, _ := strconv.Atoi(formula)
				if formulaInt <= 0 {
					br.Msg = "N值不可小于0, 重新输入"
					return
				}
			case utils.EdbBaseCalculateExponentialSmoothing:
				if v.Formula == nil {
					br.Msg = "请填写alpha值"
					return
				}
				formula, ok := v.Formula.(string)
				if !ok {
					br.Msg = "alpha值格式有误"
					return
				}
				alpha, _ := strconv.ParseFloat(formula, 64)
				if alpha <= 0 || alpha >= 1 {
					br.Msg = "alpha值应在0-1之间, 请重新输入"
					return
				}
			}
		}
	}
	edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
		return
	}
	if len(edbArr) == 0 {
		br.Msg = "因子指标系列有误"
		br.ErrMsg = "因子指标系列长度为0"
		return
	}

	// 新增指标系列
	seriesItem := new(data_manage.FactorEdbSeries)
	seriesItem.SeriesName = req.SeriesName
	seriesItem.EdbInfoType = req.EdbInfoType
	seriesItem.CreateTime = time.Now().Local()
	seriesItem.ModifyTime = time.Now().Local()
	if calculateLen > 0 {
		seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
		seriesItem.CalculateStep = calculatesJson
	}
	mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
	for _, v := range edbArr {
		mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
			EdbInfoId:  v.EdbInfoId,
			EdbCode:    v.EdbCode,
			CreateTime: time.Now().Local(),
			ModifyTime: time.Now().Local(),
		})
	}
	seriesId, e := seriesItem.CreateSeriesAndMapping(seriesItem, mappings)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增因子指标系列失败, Err: " + e.Error()
		return
	}

	// 计算指标数据
	var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
	if calculateLen > 0 {
		calculateResp, e = data.FactorEdbStepCalculate(seriesId, edbArr, req.Calculates, this.Lang, false)
		if e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
			return
		}

		// 更新系列计算状态
		cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
		seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
		seriesItem.ModifyTime = time.Now().Local()
		if e = seriesItem.Update(cols); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
			return
		}
	} else {
		for _, v := range edbArr {
			calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
				EdbInfoId: v.EdbInfoId,
				EdbCode:   v.EdbCode,
				Msg:       "保存成功",
			})
		}
	}
	calculateResp.SeriesId = seriesId

	br.Data = calculateResp
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
	br.IsAddLog = true
}

// Edit
// @Title 编辑
// @Description 编辑
// @Param	request	body request.EditFactorEdbSeriesReq true "type json string"
// @Success Ret=200 操作成功
// @router /factor_edb_series/edit [post]
func (this *FactorEdbSeriesController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		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 request.EditFactorEdbSeriesReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
		return
	}
	if req.SeriesId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", req.SeriesId)
		return
	}
	req.SeriesName = strings.TrimSpace(req.SeriesName)
	if req.SeriesName == "" {
		br.Msg = "请输入指标系列名称"
		return
	}
	if len(req.EdbInfoIds) <= 0 {
		br.Msg = "请选择因子指标系列"
		return
	}
	if len(req.EdbInfoIds) > 100 {
		br.Msg = "添加指标总数量不得超过100"
		return
	}
	calculateLen := len(req.Calculates)
	if calculateLen > 5 {
		br.Msg = "计算公式不可超过5个"
		return
	}
	var calculatesJson string
	if calculateLen > 0 {
		b, e := json.Marshal(req.Calculates)
		if e != nil {
			br.Msg = "计算方式格式有误"
			br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
			return
		}
		calculatesJson = string(b)
		for _, v := range req.Calculates {
			switch v.Source {
			case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
				if v.Formula == nil {
					br.Msg = "请输入N值"
					return
				}
				formula, ok := v.Formula.(string)
				if !ok {
					br.Msg = "N值格式有误"
					return
				}
				formulaInt, _ := strconv.Atoi(formula)
				if formulaInt <= 0 {
					br.Msg = "N值不可小于0, 重新输入"
					return
				}
			case utils.EdbBaseCalculateExponentialSmoothing:
				if v.Formula == nil {
					br.Msg = "请填写alpha值"
					return
				}
				formula, ok := v.Formula.(string)
				if !ok {
					br.Msg = "alpha值格式有误"
					return
				}
				alpha, _ := strconv.ParseFloat(formula, 64)
				if alpha <= 0 || alpha >= 1 {
					br.Msg = "alpha值应在0-1之间, 请重新输入"
					return
				}
			}
		}
	}
	seriesOb := new(data_manage.FactorEdbSeries)
	seriesItem, e := seriesOb.GetItemById(req.SeriesId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "该因子指标系列不存在"
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
		return
	}
	originCalculateState := seriesItem.CalculateState

	edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
		return
	}
	if len(edbArr) == 0 {
		br.Msg = "因子指标系列有误"
		br.ErrMsg = "因子指标系列长度为0"
		return
	}
	var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
	calculateResp.SeriesId = seriesItem.FactorEdbSeriesId

	// 如果不需要进行重新计算(比如只改了系列名称)那么只更新指标系列
	seriesItem.SeriesName = req.SeriesName
	seriesItem.EdbInfoType = req.EdbInfoType
	seriesItem.ModifyTime = time.Now().Local()
	updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime}
	if !req.Recalculate {
		if e = seriesItem.Update(updateCols); e != nil {
			br.Msg = "操作成功"
			br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error()
			return
		}
		for _, v := range edbArr {
			calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
				EdbInfoId: v.EdbInfoId,
				EdbCode:   v.EdbCode,
				Msg:       "保存成功",
			})
		}
		br.Data = calculateResp
		br.Ret = 200
		br.Success = true
		br.Msg = "操作成功"
		return
	}

	// 更新系列信息和指标关联
	seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculateNone
	if calculateLen > 0 {
		seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
		seriesItem.CalculateStep = calculatesJson
		updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep)
	}
	mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
	for _, v := range edbArr {
		mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
			EdbInfoId:  v.EdbInfoId,
			EdbCode:    v.EdbCode,
			CreateTime: time.Now().Local(),
			ModifyTime: time.Now().Local(),
		})
	}
	if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error()
		return
	}

	// 重新计算
	calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
		return
	}
	if seriesItem.CalculateState == data_manage.FactorEdbSeriesCalculating {
		seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
	}

	// 若原状态不一致, 更新状态
	if originCalculateState != seriesItem.CalculateState {
		cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
		seriesItem.ModifyTime = time.Now().Local()
		if e = seriesItem.Update(cols); e != nil {
			br.Msg = "操作失败"
			br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
			return
		}
	}

	br.Data = calculateResp
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
	br.IsAddLog = true
}

// Detail
// @Title 详情
// @Description 详情
// @Param   SeriesId  query  int  false  "多因子指标系列ID"
// @Success 200 {object} data_manage.FactorEdbSeriesDetail
// @router /factor_edb_series/detail [get]
func (this *FactorEdbSeriesController) Detail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	seriesId, _ := this.GetInt("SeriesId", 0)
	if seriesId <= 0 {
		br.Msg = "参数有误"
		br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId)
		return
	}

	seriesOb := new(data_manage.FactorEdbSeries)
	series, e := seriesOb.GetItemById(seriesId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "该因子指标系列不存在"
			return
		}
		br.Msg = "获取失败"
		br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
		return
	}

	mappingOb := new(data_manage.FactorEdbSeriesMapping)
	cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId)
	pars := make([]interface{}, 0)
	pars = append(pars, seriesId)
	mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime))
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error()
		return
	}

	resp := new(data_manage.FactorEdbSeriesDetail)
	resp.FactorEdbSeriesItem = series.Format2Item()
	for _, m := range mappings {
		resp.EdbMappings = append(resp.EdbMappings, m.Format2Item())
	}

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

// CorrelationMatrix
// @Title 因子指标系列-相关性矩阵
// @Description 因子指标系列-相关性矩阵
// @Param	request	body request.FactorEdbSeriesCorrelationMatrixReq true "type json string"
// @Success 200 {object} data_manage.FactorEdbSeriesCorrelationMatrixItem
// @router /factor_edb_series/correlation/matrix [post]
func (this *FactorEdbSeriesController) CorrelationMatrix() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		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 request.FactorEdbSeriesCorrelationMatrixReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常"
		br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
		return
	}
	if req.BaseEdbInfoId <= 0 {
		br.Msg = "请选择标的指标"
		return
	}
	if len(req.SeriesIds) == 0 {
		br.Msg = "请选择因子指标系列"
		return
	}
	if req.Correlation.LeadValue <= 0 {
		br.Msg = "分析周期不允许设置为负数或0"
		return
	}
	if req.Correlation.LeadUnit == "" {
		br.Msg = "请选择分析周期频度"
		return
	}
	leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit]
	if !ok {
		br.Msg = "错误的分析周期频度"
		br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit)
		return
	}

	if req.Correlation.CalculateUnit == "" {
		br.Msg = "请选择计算窗口频度"
		return
	}
	calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit]
	if !ok {
		br.Msg = "错误的计算窗口频度"
		br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit)
		return
	}
	leadDays := 2 * req.Correlation.LeadValue * leadUnitDays
	calculateDays := req.Correlation.CalculateValue * calculateUnitDays
	if calculateDays < leadDays {
		br.Msg = "计算窗口必须≥2*分析周期"
		return
	}

	// 矩阵计算
	var calculatePars data_manage.CalculateCorrelationMatrixPars
	calculatePars.BaseEdbInfoId = req.BaseEdbInfoId
	calculatePars.SeriesIds = req.SeriesIds
	calculatePars.Correlation = req.Correlation
	resp, _, e := correlationServ.CalculateCorrelationMatrix(calculatePars)
	if e != nil {
		br.Msg = "计算失败"
		br.ErrMsg = fmt.Sprintf("计算相关性矩阵失败, %v", e)
		return
	}

	// 获取标的指标信息及数据
	//baseEdb, e := data_manage.GetEdbInfoById(req.BaseEdbInfoId)
	//if e != nil {
	//	if e.Error() == utils.ErrNoRow() {
	//		br.Msg = "标的指标不存在"
	//		return
	//	}
	//	br.Msg = "获取失败"
	//	br.ErrMsg = "获取标的指标信息失败, Err: " + e.Error()
	//	return
	//}
	//dataListA := make([]*data_manage.EdbDataList, 0)
	//{
	//	// 标的指标数据日期区间
	//	startDate := time.Now().AddDate(0, 0, -calculateDays).Format(utils.FormatDate)
	//	endDate := time.Now().Format(utils.FormatDate)
	//	startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
	//	startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate) // 不包含第一天
	//	switch baseEdb.EdbInfoType {
	//	case 0:
	//		dataListA, e = data_manage.GetEdbDataList(baseEdb.Source, baseEdb.SubSource, baseEdb.EdbInfoId, startDate, endDate)
	//	case 1:
	//		_, dataListA, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdb.EdbInfoId, startDate, endDate, false)
	//	default:
	//		br.Msg = "获取失败"
	//		br.ErrMsg = fmt.Sprintf("标的指标类型异常: %d", baseEdb.EdbInfoType)
	//		return
	//	}
	//	if e != nil {
	//		br.Msg = "获取失败"
	//		br.ErrMsg = "获取标的指标数据失败, Err:" + e.Error()
	//		return
	//	}
	//}
	//
	//// 获取因子系列
	//seriesIdItem := make(map[int]*data_manage.FactorEdbSeries)
	//{
	//	ob := new(data_manage.FactorEdbSeries)
	//	cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().PrimaryId, utils.GetOrmInReplace(len(req.SeriesIds)))
	//	pars := make([]interface{}, 0)
	//	pars = append(pars, req.SeriesIds)
	//	items, e := ob.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", ob.Cols().PrimaryId))
	//	if e != nil {
	//		br.Msg = "获取失败"
	//		br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
	//		return
	//	}
	//	if len(items) != len(req.SeriesIds) {
	//		br.Msg = "获取失败"
	//		br.ErrMsg = "因子指标系列数量有误"
	//		return
	//	}
	//	for _, v := range items {
	//		seriesIdItem[v.FactorEdbSeriesId] = v
	//	}
	//}
	//
	//// 获取因子指标
	//edbMappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
	//edbInfoIds := make([]int, 0)
	//{
	//	ob := new(data_manage.FactorEdbSeriesMapping)
	//	cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().FactorEdbSeriesId, utils.GetOrmInReplace(len(req.SeriesIds)))
	//	pars := make([]interface{}, 0)
	//	pars = append(pars, req.SeriesIds)
	//	order := fmt.Sprintf("%s ASC, %s ASC", ob.Cols().FactorEdbSeriesId, ob.Cols().EdbInfoId)
	//	items, e := ob.GetItemsByCondition(cond, pars, []string{}, order)
	//	if e != nil {
	//		br.Msg = "获取失败"
	//		br.ErrMsg = "获取因子指标关联失败, Err: " + e.Error()
	//		return
	//	}
	//	for _, v := range items {
	//		edbInfoIds = append(edbInfoIds, v.EdbInfoId)
	//	}
	//	edbMappings = items
	//}
	//edbIdItem := make(map[int]*data_manage.EdbInfo)
	//edbItems, e := data_manage.GetEdbInfoByIdList(edbInfoIds)
	//if e != nil {
	//	br.Msg = "获取失败"
	//	br.ErrMsg = "获取因子指标失败, Err: " + e.Error()
	//	return
	//}
	//for _, v := range edbItems {
	//	edbIdItem[v.EdbInfoId] = v
	//}
	//
	//// 获取因子指标数据, 计算相关性
	//resp := new(data_manage.FactorEdbSeriesCorrelationMatrixResp)
	//calculateDataOb := new(data_manage.FactorEdbSeriesCalculateData)
	//
	//calculateWorkers := make(chan struct{}, 10)
	//wg := sync.WaitGroup{}
	//edbExists := make(map[string]bool)
	//chartKeyMap := make(map[string]*data_manage.FactorEdbSeriesChartMapping)
	//for _, v := range edbMappings {
	//	existsKey := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
	//	if edbExists[existsKey] {
	//		continue
	//	}
	//	edbExists[existsKey] = true
	//
	//	edbItem := edbIdItem[v.EdbInfoId]
	//	if edbItem == nil {
	//		continue
	//	}
	//	seriesItem := seriesIdItem[v.FactorEdbSeriesId]
	//	if seriesItem == nil {
	//		continue
	//	}
	//
	//	wg.Add(1)
	//	go func(mapping *data_manage.FactorEdbSeriesMapping, edb *data_manage.EdbInfo, series *data_manage.FactorEdbSeries) {
	//		defer func() {
	//			wg.Done()
	//			<-calculateWorkers
	//		}()
	//		calculateWorkers <- struct{}{}
	//
	//		var item data_manage.FactorEdbSeriesCorrelationMatrixItem
	//		item.SeriesId = series.FactorEdbSeriesId
	//		item.EdbInfoId = edb.EdbInfoId
	//		item.EdbCode = edb.EdbCode
	//		item.EdbName = edb.EdbName
	//
	//		// 指标来源
	//		edbList := make([]*data_manage.ChartEdbInfoMapping, 0)
	//		edbList = append(edbList, &data_manage.ChartEdbInfoMapping{
	//			EdbInfoId:           edb.EdbInfoId,
	//			EdbInfoCategoryType: edb.EdbInfoType,
	//			EdbType:             edb.EdbType,
	//			Source:              edb.Source,
	//			SourceName:          edb.SourceName,
	//		})
	//		sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
	//		item.SourceName = strings.Join(sourceNameList, ",")
	//		item.SourceNameEn = strings.Join(sourceNameEnList, ",")
	//
	//		// 获取指标数据
	//		dataListB := make([]*data_manage.EdbDataList, 0)
	//		if series.CalculateState == data_manage.FactorEdbSeriesCalculated {
	//			cond := fmt.Sprintf(" AND %s = ? AND %s = ?", calculateDataOb.Cols().FactorEdbSeriesId, calculateDataOb.Cols().EdbInfoId)
	//			pars := make([]interface{}, 0)
	//			pars = append(pars, mapping.FactorEdbSeriesId, mapping.EdbInfoId)
	//			dataItems, e := calculateDataOb.GetItemsByCondition(cond, pars, []string{calculateDataOb.Cols().DataTime, calculateDataOb.Cols().Value}, fmt.Sprintf("%s ASC", calculateDataOb.Cols().DataTime))
	//			if e != nil {
	//				item.Msg = fmt.Sprintf("计算失败")
	//				item.ErrMsg = fmt.Sprintf("获取计算数据失败, err: %v", e)
	//				resp.Fail = append(resp.Fail, item)
	//				return
	//			}
	//			dataListB = data_manage.TransEdbSeriesCalculateData2EdbDataList(dataItems)
	//		} else {
	//			switch edb.EdbInfoType {
	//			case 0:
	//				dataListB, e = data_manage.GetEdbDataList(edb.Source, edb.SubSource, edb.EdbInfoId, "", "")
	//			case 1:
	//				_, dataListB, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(edb.EdbInfoId, "", "", false)
	//			default:
	//				item.Msg = fmt.Sprintf("计算失败")
	//				item.ErrMsg = fmt.Sprintf("指标类型异常, edbType: %d", edb.EdbInfoType)
	//				resp.Fail = append(resp.Fail, item)
	//				return
	//			}
	//		}
	//
	//		// 计算相关性
	//		xEdbIdValue, yDataList, e := correlationServ.CalculateCorrelation(req.Correlation.LeadValue, req.Correlation.LeadUnit, baseEdb.Frequency, edb.Frequency, dataListA, dataListB)
	//		if e != nil {
	//			item.Msg = fmt.Sprintf("计算失败")
	//			item.ErrMsg = fmt.Sprintf("相关性计算失败, err: %v", e)
	//			resp.Fail = append(resp.Fail, item)
	//			return
	//		}
	//
	//		// X及Y轴数据
	//		yData := yDataList[0].Value
	//		yLen := len(yData)
	//		values := make([]data_manage.FactorEdbSeriesCorrelationMatrixValues, len(xEdbIdValue))
	//		for k, x := range xEdbIdValue {
	//			var y float64
	//			if k >= 0 && k < yLen {
	//				y = yData[k]
	//			}
	//			y = utils.SubFloatToFloat(y, 2)
	//			values[k] = data_manage.FactorEdbSeriesCorrelationMatrixValues{
	//				XData: x, YData: y,
	//			}
	//		}
	//
	//		// 图表关联-此处添加的chart_info_id=0
	//		newMapping := new(data_manage.FactorEdbSeriesChartMapping)
	//		newMapping.CalculateType = data_manage.FactorEdbSeriesChartCalculateTypeCorrelation
	//
	//		// 计算参数
	//		var calculatePars data_manage.FactorEdbSeriesChartCalculateCorrelationReq
	//		calculatePars.BaseEdbInfoId = req.BaseEdbInfoId
	//		calculatePars.LeadValue = req.Correlation.LeadValue
	//		calculatePars.LeadUnit = req.Correlation.LeadUnit
	//		calculatePars.CalculateValue = req.Correlation.CalculateValue
	//		calculatePars.CalculateUnit = req.Correlation.CalculateUnit
	//		bc, e := json.Marshal(calculatePars)
	//		if e != nil {
	//			item.Msg = fmt.Sprintf("计算失败")
	//			item.ErrMsg = fmt.Sprintf("计算参数JSON格式化失败, err: %v", e)
	//			resp.Fail = append(resp.Fail, item)
	//			return
	//		}
	//		newMapping.CalculatePars = string(bc)
	//
	//		// 计算结果, 注此处保存的是排序前的顺序
	//		bv, e := json.Marshal(values)
	//		if e != nil {
	//			item.Msg = fmt.Sprintf("计算失败")
	//			item.ErrMsg = fmt.Sprintf("计算结果JSON格式化失败, err: %v", e)
	//			resp.Fail = append(resp.Fail, item)
	//			return
	//		}
	//		newMapping.CalculateData = string(bv)
	//		newMapping.FactorEdbSeriesId = mapping.FactorEdbSeriesId
	//		newMapping.EdbInfoId = mapping.EdbInfoId
	//		newMapping.CreateTime = time.Now().Local()
	//		newMapping.ModifyTime = time.Now().Local()
	//		chartKeyMap[existsKey] = newMapping
	//
	//		// 按照固定规则排期数[0 1 2 3 -1 -2 -3], 仅矩阵展示为此顺序
	//		sort.Sort(data_manage.FactorEdbSeriesCorrelationMatrixOrder(values))
	//		item.Msg = "计算成功"
	//		item.Values = values
	//		resp.Success = append(resp.Success, item)
	//	}(v, edbItem, seriesItem)
	//}
	//wg.Wait()
	//
	//// 新增图表关联, 此处按照顺序添加
	//chartMappings := make([]*data_manage.FactorEdbSeriesChartMapping, 0)
	//for _, v := range edbMappings {
	//	k := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
	//	item := chartKeyMap[k]
	//	if item == nil {
	//		continue
	//	}
	//	chartMappings = append(chartMappings, item)
	//}
	//chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping)
	//if e = chartMappingOb.ClearAndCreateMapping(req.SeriesIds, chartMappings); e != nil {
	//	br.Msg = "获取失败"
	//	br.ErrMsg = fmt.Sprintf("新增图表关联失败, Err: %v", e)
	//	return
	//}

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