package data_manage

import (
	"encoding/json"
	"eta/eta_api/controllers"
	"eta/eta_api/models"
	"eta/eta_api/models/data_manage"
	"eta/eta_api/services/data"
	"eta/eta_api/services/data/data_manage_permission"
	"eta/eta_api/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"net/url"
	"strconv"
	"strings"
	"time"
)

// 计算指标
type EdbInfoCalculateController struct {
	controllers.BaseAuthController
}

// @Title 生成计算指标
// @Description 生成计算指标接口
// @Param	request	body data_manage.EdbInfoCalculateSaveReq true "type json string"
// @Success Ret=200 返回图表id
// @router /edb_info/calculate/save [post]
func (this *ChartInfoController) CalculateSave() {
	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 data_manage.EdbInfoCalculateSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		return
	}

	if req.Frequency == "" {
		br.Msg = "频率不能为空"
		return
	}

	if req.Unit == "" {
		br.Msg = "单位不能为空"
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	if len(req.EdbInfoIdArr) <= 0 {
		br.Msg = "请选择指标"
		return
	}

	if req.CalculateFormula == "" {
		br.Msg = "请填写指标"
		return
	}
	calculateFormula := req.CalculateFormula
	calculateFormula = strings.Replace(calculateFormula, "（", "(", -1)
	calculateFormula = strings.Replace(calculateFormula, "）", ")", -1)
	calculateFormula = strings.Replace(calculateFormula, "，", ",", -1)
	calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
	calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
	req.CalculateFormula = calculateFormula

	//判断是否重复指标
	edbInfoMap := make(map[int]string)
	//移除研究员选择指标中的未使用的指标
	{
		//转大写的计算公式
		upperCalculateFormulaStr := strings.ToUpper(req.CalculateFormula)
		//用到的指标
		newEdbInfoIdArr := make([]data_manage.EdbInfoFromTag, 0)
		for _, tmpEdbInfo := range req.EdbInfoIdArr {
			_, ok := edbInfoMap[tmpEdbInfo.EdbInfoId]
			if ok {
				br.Msg = "选择指标失败，请勿选择重复指标！"
				return
			}
			edbInfoMap[tmpEdbInfo.EdbInfoId] = tmpEdbInfo.FromTag

			upperFromTag := strings.ToUpper(tmpEdbInfo.FromTag)
			if strings.Contains(upperCalculateFormulaStr, upperFromTag) {
				newEdbInfoIdArr = append(newEdbInfoIdArr, tmpEdbInfo)
			}
		}
		req.EdbInfoIdArr = newEdbInfoIdArr
	}

	var condition string
	var pars []interface{}
	condition += " AND edb_name=? "
	pars = append(pars, req.EdbName)

	count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
	if err != nil {
		br.Msg = "判断指标名称是否存在失败"
		br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
		return
	}

	if count > 0 {
		br.Msg = "指标名称已存在，请重新填写"
		br.ErrMsg = "指标名称已存在，请重新填写"
		br.IsSendEmail = false
		return
	}
	//检验公式
	var formulaStr string
	var edbInfoIdBytes []string
	for _, v := range req.EdbInfoIdArr {
		formulaStr += v.FromTag + ","
		edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
	}

	formulaSlice, err := data.CheckFormulaJson(req.CalculateFormula)
	if err != nil {
		br.Msg = "公式格式错误，请重新填写"
		return
	}
	for _, formula := range formulaSlice {
		formulaMap := data.CheckFormula(formula)
		for _, v := range formulaMap {
			if !strings.Contains(formulaStr, v) {
				br.Msg = "公式错误，请重新填写"
				return
			}
		}
	}

	// 调用指标库去新增
	req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
		AdminId:   sysUser.AdminId,
		AdminName: sysUser.RealName,
		//EdbInfoId:        req.EdbInfoId,
		EdbName:          req.EdbName,
		Frequency:        req.Frequency,
		Unit:             req.Unit,
		ClassifyId:       req.ClassifyId,
		CalculateFormula: req.CalculateFormula,
		EdbInfoIdArr:     req.EdbInfoIdArr,
		EmptyType:        req.EmptyType,
		MaxEmptyType:     req.MaxEmptyType,
		Extra:            req.Extra,
	}
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.AddEdbCalculateData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "新增失败"
		br.ErrMsg = "新增失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

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

// CalculateDetail
// @Title 获取计算指标详情
// @Description 获取计算指标详情接口
// @Param   EdbInfoId   query   int  true       "指标id"
// @Success 200 {object} data_manage.CalculateDetailResp
// @router /edb_info/calculate/detail [get]
func (this *ChartInfoController) CalculateDetail() {
	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
	}
	edbInfoId, _ := this.GetInt("EdbInfoId")
	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}

	calculateList, err := data_manage.GetEdbInfoCalculateDetail(edbInfoId, edbInfo.Source)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}

	fullEdb := new(data_manage.EdbInfoFullClassify)
	classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfo.ClassifyId)
	if err != nil {
		br.Msg = err.Error()
		br.ErrMsg = errMsg
		return
	}

	fullEdb.EdbInfo = edbInfo
	fullEdb.ClassifyList = classifyList

	var currClassifyItem *data_manage.EdbClassifyIdItems
	for _, v := range classifyList {
		if v.ClassifyId == edbInfo.ClassifyId {
			currClassifyItem = v
		}
	}
	if currClassifyItem != nil {
		haveOperaAuth, err := data_manage_permission.CheckEdbPermission(edbInfo.IsJoinPermission, currClassifyItem.IsJoinPermission, sysUser.AdminId, edbInfo.EdbInfoId, edbInfo.ClassifyId)
		if err != nil {
			br.Msg = err.Error()
			br.ErrMsg = "校验指标权限失败，err:" + err.Error()
			return
		}
		fullEdb.HaveOperaAuth = haveOperaAuth
	}

	// 拟合残差计算相关系数
	if fullEdb.HaveOperaAuth && edbInfo.Source == utils.DATA_SOURCE_CALCULATE_NHCC {
		var aEdbInfo, bEdbInfo *data_manage.EdbInfoCalculateDetail
		for _, v := range calculateList {
			if v.FromTag == "A" {
				aEdbInfo = v
				continue
			}
			if v.FromTag == "B" {
				bEdbInfo = v
				continue
			}
		}
		if aEdbInfo != nil && bEdbInfo != nil {
			edbInfoFromTagList := []data_manage.EdbInfoFromTag{
				{
					EdbInfoId: aEdbInfo.FromEdbInfoId,
					FromTag:   aEdbInfo.FromTag,
					MoveValue: aEdbInfo.MoveValue,
				}, {
					EdbInfoId: bEdbInfo.FromEdbInfoId,
					FromTag:   bEdbInfo.FromTag,
					MoveValue: bEdbInfo.MoveValue,
				},
			}

			req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
				AdminId:      sysUser.AdminId,
				AdminName:    sysUser.RealName,
				Formula:      edbInfo.CalculateFormula,
				EdbInfoIdArr: edbInfoFromTagList,
			}

			// 计算
			val, err, _ := data.CallCalculateComputeCorrelation(req2, this.Lang)
			if err == nil {
				fullEdb.CorrelationStr = val
			}
		}

	}

	resp := new(data_manage.CalculateDetailResp)
	resp.EdbInfoDetail = fullEdb
	resp.CalculateList = calculateList
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
}

// @Title 修改计算指标
// @Description 修改计算指标接口
// @Param	request	body data_manage.EdbInfoCalculateEditReq true "type json string"
// @Success Ret=200 返回图表id
// @router /edb_info/calculate/edit [post]
func (this *ChartInfoController) CalculateEdit() {
	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 data_manage.EdbInfoCalculateEditReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.EdbInfoId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "指标ID：" + strconv.Itoa(req.EdbInfoId)
		return
	}

	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		return
	}

	if req.Frequency == "" {
		br.Msg = "频率不能为空"
		return
	}

	if req.Unit == "" {
		br.Msg = "单位不能为空"
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	if len(req.EdbInfoIdArr) <= 0 {
		br.Msg = "请选择指标"
		return
	}

	if req.CalculateFormula == "" {
		br.Msg = "请填写指标"
		return
	}

	calculateFormula := req.CalculateFormula
	calculateFormula = strings.Replace(calculateFormula, "（", "(", -1)
	calculateFormula = strings.Replace(calculateFormula, "）", ")", -1)
	calculateFormula = strings.Replace(calculateFormula, "，", ",", -1)
	calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
	calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
	req.CalculateFormula = calculateFormula
	fmt.Println("calculateFormula:" + calculateFormula)

	//判断是否重复指标
	edbInfoMap := make(map[int]string)
	//移除研究员选择指标中的未使用的指标
	{
		//转大写的计算公式
		upperCalculateFormulaStr := strings.ToUpper(req.CalculateFormula)
		//用到的指标
		newEdbInfoIdArr := make([]data_manage.EdbInfoFromTag, 0)
		for _, tmpEdbInfo := range req.EdbInfoIdArr {
			_, ok := edbInfoMap[tmpEdbInfo.EdbInfoId]
			if ok {
				br.Msg = "选择指标失败，请勿选择重复指标！"
				return
			}
			edbInfoMap[tmpEdbInfo.EdbInfoId] = tmpEdbInfo.FromTag

			upperFromTag := strings.ToUpper(tmpEdbInfo.FromTag)
			if strings.Contains(upperCalculateFormulaStr, upperFromTag) {
				newEdbInfoIdArr = append(newEdbInfoIdArr, tmpEdbInfo)
			}
		}
		req.EdbInfoIdArr = newEdbInfoIdArr
	}

	var condition string
	var pars []interface{}
	condition += " AND edb_name=? "
	pars = append(pars, req.EdbName)

	condition += " AND edb_info_id<>? "
	pars = append(pars, req.EdbInfoId)

	count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
	if err != nil {
		br.Msg = "判断指标名称是否存在失败"
		br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
		return
	}

	if count > 0 {
		br.Msg = "指标名称已存在，请重新填写"
		br.ErrMsg = "指标名称已存在，请重新填写"
		br.IsSendEmail = false
		return
	}

	//判断公式，指标是否有改动
	edbInfoDetail, err := data_manage.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		br.Msg = "修改失败"
		br.Msg = "获取指标信息失败,GetEdbInfoById Err:" + err.Error()
		return
	}
	if edbInfoDetail == nil {
		br.Msg = "修改失败"
		br.Msg = "指标信息不存在，EdbInfoId:" + strconv.Itoa(req.EdbInfoId)
		return
	}

	// 调用指标库去更新
	req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
		AdminId:          sysUser.AdminId,
		AdminName:        sysUser.RealName,
		EdbInfoId:        req.EdbInfoId,
		EdbName:          req.EdbName,
		Frequency:        req.Frequency,
		Unit:             req.Unit,
		ClassifyId:       req.ClassifyId,
		CalculateFormula: req.CalculateFormula,
		EdbInfoIdArr:     req.EdbInfoIdArr,
		EmptyType:        req.EmptyType,
		MaxEmptyType:     req.MaxEmptyType,
		Extra:            req.Extra,
	}
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.EditEdbCalculateData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "编辑失败"
		br.ErrMsg = "编辑失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(req.EdbInfoId)

	// 修改关联的预测指标基础信息
	go data.ModifyPredictEdbBaseInfoBySourceEdb(edbInfoDetail, req.Frequency, req.Unit)

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

// CalculateBatchSave
// @Title 累计值转月-同比值-同差等计算新增
// @Description 累计值转月-同比值-同差等计算新增接口
// @Param	request	body data_manage.EdbInfoCalculateBatchSaveReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/batch/save [post]
func (this *ChartInfoController) CalculateBatchSave() {
	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 data_manage.EdbInfoCalculateBatchSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	req.EdbName = strings.Trim(req.EdbName, " ")
	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		return
	}

	if req.Frequency == "" {
		br.Msg = "频率不能为空"
		return
	}

	if req.Unit == "" {
		br.Msg = "单位不能为空"
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	fromEdbInfoId := req.FromEdbInfoId

	var formulaInt int
	switch req.Source {
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS, utils.DATA_SOURCE_CALCULATE_HBZ, utils.DATA_SOURCE_CALCULATE_HCZ, utils.DATA_SOURCE_CALCULATE_TIME_SHIFT, utils.DATA_SOURCE_CALCULATE_CJJX:
		if req.Formula == "" {
			br.Msg = "请填写N值"
			return
		}
		formulaInt, _ = strconv.Atoi(req.Formula)
		if formulaInt <= 0 {
			br.Msg = "N值输入错误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		//直接拼接指标
		//校验时间格式
		_, err = time.ParseInLocation(utils.FormatDate, req.Formula, time.Local)
		if err != nil {
			br.Msg = "拼接日期有误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_NHCC: //拟合残差指标
		//指标校验
		if len(req.EdbInfoIdArr) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}
		fromEdbInfoId = req.EdbInfoIdArr[0].EdbInfoId

		//校验时间格式
		//数据格式：2022-11-01,2022-11-10
		timeList := strings.Split(req.Formula, ",")
		if len(timeList) != 2 {
			br.Msg = "选择时间有误,请重新输入"
			return
		}
		startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
		if err != nil {
			br.Msg = "开始日期有误,请重新输入"
			return
		}
		endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
		if err != nil {
			br.Msg = "结束日期有误,请重新输入"
			return
		}
		if utils.GetTimeSubDay(startDate, endDate) < 2 {
			br.Msg = "日期间隔不得少于两天"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZSXY: // 指数修匀
		if req.Formula == "" {
			br.Msg = "请填写alpha值"
			return
		}
		alpha, e := strconv.ParseFloat(req.Formula, 64)
		if e != nil {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
		if alpha <= 0 || alpha >= 1 {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
	}

	notNeedFromEdbSourceList := []int{utils.DATA_SOURCE_CALCULATE_KSZS} // 不需要传入来源指标id的 指标类型
	if fromEdbInfoId <= 0 && !utils.InArrayByInt(notNeedFromEdbSourceList, req.Source) {
		br.Msg = "请选择指标"
		return
	}

	//加入缓存机制，避免创建同一个名称的指标 start
	redisKey := fmt.Sprint("edb_info:calculate:batch:save:", req.Source, ":", req.EdbName)
	isExist := utils.Rc.IsExist(redisKey)
	if isExist {
		br.Msg = "指标正在处理,请勿重复提交"
		return
	} else {
		//设置3分钟缓存
		utils.Rc.SetNX(redisKey, 1, time.Second*300)
		defer func() {
			utils.Rc.Delete(redisKey)
		}()
	}
	//加入缓存机制，避免创建同一个名称的指标 end

	req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
		AdminId:          sysUser.AdminId,
		AdminName:        sysUser.RealName,
		EdbInfoId:        req.EdbInfoId,
		EdbName:          req.EdbName,
		Frequency:        req.Frequency,
		Unit:             req.Unit,
		ClassifyId:       req.ClassifyId,
		Formula:          req.Formula, //N数值移动平均计算、环比值、环差值
		FromEdbInfoId:    req.FromEdbInfoId,
		CalculateFormula: req.CalculateFormula,
		Source:           req.Source,
		MoveType:         req.MoveType,
		MoveFrequency:    req.MoveFrequency,

		//CalculateFormula: edbInfo.CalculateFormula,
		EdbInfoIdArr: req.EdbInfoIdArr,
		Calendar:     req.Calendar,
		Extra:        req.Extra,
	}

	// 调用指标库去更新
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.BatchSaveEdbCalculateData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "新增失败"
		br.ErrMsg = "新增失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

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

// @Title 累计值转月-同比值-同差等计算编辑
// @Description 累计值转月-同比值-同差等计算编辑接口
// @Param	request	body data_manage.EdbInfoCalculateBatchEditReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/batch/edit [post]
func (this *ChartInfoController) CalculateBatchEdit() {
	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 data_manage.EdbInfoCalculateBatchEditReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.EdbName == "" {
		br.Msg = "指标名称不能为空"
		return
	}

	if req.Frequency == "" {
		br.Msg = "频率不能为空"
		return
	}

	if req.Unit == "" {
		br.Msg = "单位不能为空"
		return
	}

	if req.ClassifyId <= 0 {
		br.Msg = "请选择分类"
		return
	}

	if req.EdbInfoId <= 0 {
		br.Msg = "请选择指标"
		return
	}

	var condition string
	var pars []interface{}
	condition += " AND edb_name=? "
	pars = append(pars, req.EdbName)

	condition += " AND edb_info_id<>? "
	pars = append(pars, req.EdbInfoId)

	count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
	if err != nil {
		br.Msg = "判断指标名称是否存在失败"
		br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
		return
	}

	if count > 0 {
		br.Msg = "指标名称已存在，请重新填写"
		br.ErrMsg = "指标名称已存在，请重新填写"
		br.IsSendEmail = false
		return
	}

	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "指标已被删除，请刷新页面"
			br.ErrMsg = "指标已被删除，请刷新页面:Err:" + err.Error()
			return
		}
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
		return
	}

	if req.Source <= 0 {
		req.Source = edbInfo.Source
	}

	var formulaInt int
	switch req.Source {
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS, utils.DATA_SOURCE_CALCULATE_HBZ, utils.DATA_SOURCE_CALCULATE_HCZ, utils.DATA_SOURCE_CALCULATE_TIME_SHIFT, utils.DATA_SOURCE_CALCULATE_CJJX:
		if req.Formula == "" {
			br.Msg = "请填写N值"
			return
		}
		formulaInt, _ = strconv.Atoi(req.Formula)
		if formulaInt <= 0 {
			br.Msg = "N值输入错误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		//直接拼接指标

		//校验时间格式
		_, err = time.ParseInLocation(utils.FormatDate, req.Formula, time.Local)
		if err != nil {
			br.Msg = "拼接日期有误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_NHCC: //拟合残差指标
		//指标校验
		if len(req.EdbInfoIdArr) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}

		//校验时间格式
		//数据格式：2022-11-01,2022-11-10
		timeList := strings.Split(req.Formula, ",")
		if len(timeList) != 2 {
			br.Msg = "选择时间有误,请重新输入"
			return
		}
		startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
		if err != nil {
			br.Msg = "开始日期有误,请重新输入"
			return
		}
		endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
		if err != nil {
			br.Msg = "结束日期有误,请重新输入"
			return
		}
		if utils.GetTimeSubDay(startDate, endDate) < 2 {
			br.Msg = "日期间隔不得少于两天"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZSXY: // 指数修匀
		if req.Formula == "" {
			br.Msg = "请填写alpha值"
			return
		}
		alpha, e := strconv.ParseFloat(req.Formula, 64)
		if e != nil {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
		if alpha <= 0 || alpha >= 1 {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
	}

	// 构造请求
	req2 := &data_manage.EdbInfoCalculateBatchEditReqByEdbLib{
		EdbInfoId:     req.EdbInfoId,
		EdbName:       req.EdbName,
		Frequency:     req.Frequency,
		Unit:          req.Unit,
		ClassifyId:    req.ClassifyId,
		Formula:       req.Formula, //N数值移动平均计算、环比值、环差值
		FromEdbInfoId: req.FromEdbInfoId,
		Source:        req.Source,
		MoveType:      req.MoveType,
		MoveFrequency: req.MoveFrequency,
		EdbInfoIdArr:  req.EdbInfoIdArr,
		Calendar:      req.Calendar,
		Extra:         req.Extra,
	}

	// 调用指标库去更新
	reqJson, err := json.Marshal(req2)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.BatchEditEdbCalculateData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "编辑失败"
		br.ErrMsg = "编辑失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	resp := respItem.Data

	//添加es
	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)

	// 修改关联的预测指标基础信息
	go data.ModifyPredictEdbBaseInfoBySourceEdb(edbInfo, req.Frequency, req.Unit)

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

// @Title 累计值转月-同比值-同差等重新计算
// @Description 累计值转月-同比值-同差等重新计算接口
// @Param	request	body data_manage.EdbInfoCalculateBatchSaveReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/batch/reset [post]
func (this *ChartInfoController) CalculateBatchReset() {
	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 data_manage.EdbInfoCalculateBatchSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.EdbInfoId <= 0 {
		br.Msg = "参数错误"
		br.ErrMsg = "参数错误:EdbInfoId:" + strconv.Itoa(req.EdbInfoId)
		return
	}

	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "指标已被删除，请刷新页面"
			br.ErrMsg = "指标已删除，请刷新页面:Err:" + err.Error()
			return
		}
		br.Msg = "重新计算失败"
		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
		return
	}

	uniqueCode := edbInfo.UniqueCode
	sourName := edbInfo.SourceName
	edbInfoId := edbInfo.EdbInfoId
	//if source == utils.DATA_SOURCE_CALCULATE {
	//	//检验公式
	//	var formulaStr string
	//	var edbInfoIdBytes []string
	//	for _, v := range fromEdbInfoList {
	//		formulaStr += v.FromTag + ","
	//		edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
	//	}
	//	formulaStr = strings.Trim(formulaStr, ",")
	//	formulaMap := data.CheckFormula(req.CalculateFormula)
	//	for _, v := range formulaMap {
	//		if !strings.Contains(formulaStr, v) {
	//			br.Msg = "公式错误，请重新填写"
	//			return
	//		}
	//	}
	//
	//	edbInfoList := make([]*data_manage.EdbInfo, 0)
	//
	//	for _, v := range fromEdbInfoList {
	//		edbInfo, err := data_manage.GetEdbInfoById(v.FromEdbInfoId)
	//		if err != nil {
	//			if err.Error() == utils.ErrNoRow() {
	//				br.Msg = "重新计算失败"
	//				br.Msg = "指标 " + strconv.Itoa(v.FromEdbInfoId) + " 不存在"
	//				return
	//			}
	//			br.Msg = "重新计算失败"
	//			br.Msg = "获取指标失败:Err:" + err.Error()
	//			return
	//		}
	//		edbInfoList = append(edbInfoList, edbInfo)
	//	}
	//	//清除历史数据
	//	err = data_manage.DeleteCalculateData(edbInfoId)
	//	if err != nil {
	//		br.Msg = "重新计算失败"
	//		br.Msg = "获取指标失败:Err:" + err.Error()
	//		return
	//	}
	//	err = data.Calculate(edbInfoList, int(edbInfoId), edbCode, edbInfo.CalculateFormula, edbInfoIdBytes)
	//	if err != nil {
	//		br.Msg = "重新计算失败"
	//		br.Msg = "生成计算指标失败,Calculate Err:" + err.Error()
	//		return
	//	}
	//} else if source == utils.DATA_SOURCE_CALCULATE_LJZZY {
	//	_, err = data_manage.AddCalculateLjzzy(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName)
	//} else if source == utils.DATA_SOURCE_CALCULATE_TBZ {
	//	sourName = "同比值"
	//	edbInfoId, err = data_manage.AddCalculateTbz(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName)
	//} else if source == utils.DATA_SOURCE_CALCULATE_TCZ {
	//	sourName = "同差值"
	//	edbInfoId, err = data_manage.AddCalculateTcz(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName)
	//} else if source == utils.DATA_SOURCE_CALCULATE_NSZYDPJJS {
	//	sourName = "N数值移动平均计算"
	//	formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
	//	edbInfoId, err = data_manage.AddCalculateNszydpjjs(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName, formulaInt)
	//} else if source == utils.DATA_SOURCE_CALCULATE_HBZ {
	//	sourName = "环比值"
	//	formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
	//	edbInfoId, err = data_manage.AddCalculateHbz(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName, formulaInt)
	//} else if source == utils.DATA_SOURCE_CALCULATE_HCZ {
	//	sourName = "环差值"
	//	formulaInt, _ := strconv.Atoi(edbInfo.CalculateFormula)
	//	edbInfoId, err = data_manage.AddCalculateHcz(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName, formulaInt)
	//} else if source == utils.DATA_SOURCE_CALCULATE_BP {
	//	sourName = "变频"
	//	edbInfoId, err = data_manage.AddCalculateBp(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName)
	//} else if source == utils.DATA_SOURCE_CALCULATE_TIME_SHIFT {
	//	sourName = "时间移位"
	//	if req.MoveFrequency == "" {
	//		req.MoveFrequency = edbInfo.MoveFrequency
	//	}
	//	if req.Formula == "" {
	//		req.Formula = edbInfo.CalculateFormula
	//	}
	//	edbInfoId, err = data_manage.AddCalculateTimeShift(&req, fromEdbInfo, edbCode, uniqueCode, sysUser.AdminId, sysUser.RealName)
	//} else if source == utils.DATA_SOURCE_CALCULATE_ZJPJ {
	//	sourName = "直接拼接"
	//	err = data_manage.RefreshAllCalculateZjpj(edbInfo)
	//} else if source == utils.DATA_SOURCE_CALCULATE_LJZTBPJ {
	//	sourName = "累计值同比拼接"
	//	err = data_manage.RefreshAllCalculateLjztbpj(edbInfo)
	//} else {
	//	br.Msg = "无效计算方式"
	//	br.ErrMsg = "无效计算方式,source:" + strconv.Itoa(source)
	//	return
	//}

	// 重新计算
	err, isAsync := data.EdbInfoRefreshAllFromBaseV2(edbInfoId, true, false)
	if err != nil {
		fmt.Println(edbInfoId, "RefreshEdbCalculateData err", time.Now())
		br.Msg = "重新计算失败"
		br.ErrMsg = "生成" + sourName + "失败,RefreshEdbCalculateData Err:" + err.Error()
		return
	}

	resp := new(data_manage.AddEdbInfoResp)
	resp.EdbInfoId = edbInfoId
	resp.UniqueCode = uniqueCode
	br.Ret = 200
	br.Success = true
	br.Msg = "重新计算成功"
	if isAsync {
		br.Msg = "该指标关联指标较多，请10分钟后刷新页面查看最新数据"
	}
	br.Data = resp
	br.IsAddLog = true
}

//累计值转月值
//func init() {
//	fmt.Println("start CalculateBatchSave")
//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
//	req.EdbInfoId = 100282
//
//	randStr := utils.GetRandDigit(4)
//	edbCode := `C` + time.Now().Format("060102") + randStr
//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
//	data_manage.AddCalculateLjzzy(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
//	fmt.Println("end CalculateBatchSave")
//	return
//}

////同比值
//func init() {
//	fmt.Println("start AddCalculateTbz")
//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
//	req.EdbInfoId = 100092
//
//	randStr := utils.GetRandDigit(4)
//	edbCode := `C` + time.Now().Format("060102") + randStr
//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
//
//	data_manage.AddCalculateTbz(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
//	fmt.Println("end AddCalculateTbz")
//	return
//}
//同差值

//func init() {
//	fmt.Println("start AddCalculateTbz")
//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
//	req.EdbInfoId = 100092
//
//	randStr := utils.GetRandDigit(4)
//	edbCode := `C` + time.Now().Format("060102") + randStr
//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.EdbInfoId)
//
//	data_manage.AddCalculateTcz(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck")
//
//	fmt.Println("end AddCalculateTbz")
//	return
//}

//N数值移动平均计算
//func init() {
//	fmt.Println("start AddCalculateTbz")
//	req := new(data_manage.EdbInfoCalculateBatchSaveReq)
//	req.FromEdbInfoId = 100081
//
//	randStr := utils.GetRandDigit(4)
//	edbCode := `C` + time.Now().Format("060102") + randStr
//	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
//	uniqueCode := utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
//	fromEdbInfo, _ := data_manage.GetEdbInfoById(req.FromEdbInfoId)
//	formulaInt := 3
//	fmt.Println("edbCode:", edbCode)
//	data_manage.AddCalculateNszydpjjs(req, fromEdbInfo, edbCode, uniqueCode, 1, "rdluck", formulaInt)
//
//	fmt.Println("end AddCalculateTbz")
//	return
//}

// ExecPythonCode
// @Title 执行python代码
// @Description 执行python代码接口
// @Param	request	body data_manage.EdbInfoCalculateSaveReq true "type json string"
// @Success Ret=200 返回图表id
// @router /edb_info/python/exec [post]
func (this *ChartInfoController) ExecPythonCode() {
	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 data_manage.ExecPythonEdbReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if req.PythonCode == "" {
		br.Msg = "python代码不能为空"
		return
	}

	resp, err := data.ExecPythonCode(req.PythonCode)
	if err != nil {
		br.Msg = "python代码执行失败，请检查代码"
		br.ErrMsg = "python代码执行失败,Err:" + err.Error()
		return
	}
	if resp.Ret != 200 {
		br.Msg = "python代码执行失败，请检查代码:" + resp.Msg
		br.ErrMsg = "python代码执行失败,Err:" + resp.ErrMsg
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "运行成功"
	br.Data = resp.Data
}

// AddPythonEdb
// @Title 添加python指标
// @Description 添加python指标接口
// @Param	request	body data_manage.AddPythonEdbReq true "type json string"
// @Success 200 {object} data_manage.AddEdbInfoResp
// @router /edb_info/python/add [post]
func (this *ChartInfoController) AddPythonEdb() {
	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 data_manage.PostAddPythonEdbReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	//传入操作人
	req.AdminId = sysUser.AdminId
	req.AdminName = sysUser.RealName
	reqJson, err := json.Marshal(req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	// 判断指标名称是否重复
	{
		var condition string
		var pars []interface{}
		condition += " AND edb_name=? "
		pars = append(pars, req.EdbName)

		condition += " AND edb_info_id<>? "
		pars = append(pars, req.EdbInfoId)

		count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
		if err != nil {
			br.Msg = "判断指标名称是否存在失败"
			br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
			return
		}
		if count > 0 {
			br.Msg = "指标名称已存在，请重新填写"
			br.ErrMsg = "指标名称已存在，请重新填写"
			br.IsSendEmail = false
			return
		}
	}
	// 添加python指标
	respItem, err := data.AddPythonEdbData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "添加失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = "添加失败"
		br.ErrMsg = respItem.ErrMsg + ";EdbName:" + req.EdbName
		return
	}
	respData := respItem.Data.(map[string]interface{})
	tmpEdbInfoId, ok := respData["EdbInfoId"]
	if !ok {
		br.Msg = `数据转换异常`
		br.ErrMsg = fmt.Sprint("respData.EdbInfoId 数据转换异常;respData:", respData)
		return
	}
	//指标id
	edbInfoId := int64(tmpEdbInfoId.(float64))

	uniqueCode, ok := respData["UniqueCode"]
	if !ok {
		br.Msg = `数据转换异常`
		br.ErrMsg = fmt.Sprint("respData.UniqueCode 数据转换异常;respData:", respData)
		return
	}
	//添加es
	data.AddOrEditEdbInfoToEs(int(edbInfoId))

	//
	resp := data_manage.AddEdbInfoResp{
		EdbInfoId:  int(edbInfoId),
		UniqueCode: uniqueCode.(string),
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// EditPythonEdb
// @Title 修改python运算指标
// @Description 修改python运算指标接口
// @Param	request	body data_manage.AddPythonEdbReq true "type json string"
// @Success Ret=200 返回成功
// @router /edb_info/python/edit [post]
func (this *ChartInfoController) EditPythonEdb() {
	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 data_manage.PostAddPythonEdbReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	//传入操作人
	req.AdminId = sysUser.AdminId
	req.AdminName = sysUser.RealName
	reqJson, err := json.Marshal(req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	// 判断指标名称是否重复
	{
		var condition string
		var pars []interface{}
		condition += " AND edb_name=? "
		pars = append(pars, req.EdbName)

		condition += " AND edb_info_id<>? "
		pars = append(pars, req.EdbInfoId)

		count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
		if err != nil {
			br.Msg = "判断指标名称是否存在失败"
			br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
			return
		}
		if count > 0 {
			br.Msg = "指标名称已存在，请重新填写"
			br.ErrMsg = "指标名称已存在，请重新填写"
			br.IsSendEmail = false
			return
		}
	}
	//获取指标信息
	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			br.Msg = "指标已被删除，请刷新页面"
			br.ErrMsg = "指标已被删除，请刷新页面:Err:" + err.Error()
			return
		}
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标信息失败:Err:" + err.Error()
		return
	}

	// 修改python运算指标
	respItem, err := data.EditPythonEdbData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "保存失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = "保存失败"
		br.ErrMsg = respItem.ErrMsg + ";EdbName:" + req.EdbName
		return
	}

	//添加es
	data.AddOrEditEdbInfoToEs(req.EdbInfoId)
	resp := new(data_manage.AddEdbInfoResp)
	resp.EdbInfoId = req.EdbInfoId
	resp.UniqueCode = edbInfo.UniqueCode
	br.Ret = 200
	br.Success = true
	br.Data = resp
	br.Msg = "保存成功"
	br.IsAddLog = true
}

// GetPythonEdbCode
// @Title 获取python代码
// @Description 获取python代码接口
// @Param   EdbInfoId   query   int  true       "指标id"
// @Success 200 {object} data_manage.PythonEdbDetailResp
// @router /edb_info/python/detail [get]
func (this *ChartInfoController) GetPythonEdbCode() {
	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
	}
	edbInfoId, _ := this.GetInt("EdbInfoId")
	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}

	if edbInfo.Source != utils.DATA_SOURCE_PYTHON {
		br.Msg = "该指标不是Python运算指标"
		br.ErrMsg = "该指标不是Python运算指标"
		return
	}

	pythonCode, err := data_manage.GetEdbPythonCodeById(edbInfoId)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + err.Error()
		return
	}

	resp := data_manage.PythonEdbDetailResp{
		EdbInfoDetail: edbInfo,
		PythonCode:    pythonCode.PythonCode,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
}

// QueryEdbDataTable
// @Title 指标筛选接口
// @Description 指标筛选接口
// @Param   EdbInfoId   query   int  false       "指标id"
// @Success 200 {object} data_manage.EdbInfoList
// @router /edb_data/table/detail [get]
func (this *EdbInfoController) QueryEdbDataTable() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	edbInfoId, _ := this.GetInt("EdbInfoId")
	if edbInfoId <= 0 {
		br.Msg = "请选择指标"
		br.ErrMsg = "请选择指标"
		return
	}

	edbInfo, err := data_manage.GetEdbInfoById(edbInfoId)
	if err != nil {
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标信息失败，err:" + err.Error()
		return
	}
	columnList := []map[string]string{
		{
			"edb_code": "指标code",
		},
		{
			"data_time": "指标日期",
		},
		{
			"value": "指标对应的值",
		},
	}

	tableName := data_manage.GetEdbDataTableName(edbInfo.Source, edbInfo.SubSource)

	var templateStr string
	if edbInfo.Source == utils.DATA_SOURCE_BUSINESS {
		templateStr = fmt.Sprintf("# 查询条件\nquery = {\"edb_code\": \"%s\"}\n# 排序\nsort = [(\"data_time\", -1)]  # -1 表示降序排列，对应 SQL 的 DESC\nprojection = {\"data_time\": 1, \"value\": 1, \"_id\": 0}  # 只选择data_time和value字段，忽略_id字段\n# 使用 find() 方法获取数据，然后使用 aggregate() 转换为列表\nraw_data = list(collection.find(query, projection).sort(sort))\n# 将结果转换为 DataFrame\nraw = pd.DataFrame(raw_data)\n# 转换data_time字段为本地时区时间\nraw['data_time'] = raw['data_time'].apply(lambda x: x.replace(tzinfo=utc_tz)).dt.tz_convert(local_tz).dt.strftime('%s')", edbInfo.EdbCode, "%Y-%m-%d")
	} else {
		templateStr = fmt.Sprintf("sql1 = f\"\"\"SELECT data_time,`value` FROM %s WHERE edb_code = '%s' ORDER BY data_time DESC;\"\"\"\nraw = pandas_fetch_all(sql1, db)", tableName, edbInfo.EdbCode)
	}
	info := data_manage.TableInfoResp{
		ColumnList:  columnList,
		TableName:   tableName,
		TemplateStr: url.PathEscape(templateStr),
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = info
}

// SaveAdjustEdbInfo
// @Title 保存数据调整接口
// @Description 保存数据调整接口
// @Param	request	body data_manage.AddPythonEdbReq true "type json string"
// @Success 200 {object} data_manage.AddEdbInfoResp
// @router /edb_info/adjust/save [post]
func (this *ChartInfoController) SaveAdjustEdbInfo() {
	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 data_manage.SaveAdjustEdbInfoReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	//传入操作人
	req.AdminId = sysUser.AdminId
	req.AdminName = sysUser.RealName
	reqJson, err := json.Marshal(req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	// 判断指标名称是否重复
	{
		var condition string
		var pars []interface{}
		condition += " AND edb_name=? "
		pars = append(pars, req.EdbName)

		condition += " AND edb_info_id<>? "
		pars = append(pars, req.EdbInfoId)

		count, err := data_manage.GetEdbInfoCountByCondition(condition, pars)
		if err != nil {
			br.Msg = "判断指标名称是否存在失败"
			br.ErrMsg = "判断指标名称是否存在失败,Err:" + err.Error()
			return
		}
		if count > 0 {
			br.Msg = "指标名称已存在，请重新填写"
			br.ErrMsg = "指标名称已存在，请重新填写"
			br.IsSendEmail = false
			return
		}
	}
	// 添加数据调整指标
	respItem, err := data.SaveAdjustEdbInfo(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "添加失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = "添加失败"
		br.ErrMsg = respItem.ErrMsg + ";EdbName:" + req.EdbName
		return
	}
	respData := respItem.Data.(map[string]interface{})
	tmpEdbInfoId, ok := respData["EdbInfoId"]
	if !ok {
		br.Msg = `数据转换异常`
		br.ErrMsg = fmt.Sprint("respData.EdbInfoId 数据转换异常;respData:", respData)
		return
	}
	//指标id
	edbInfoId := int64(tmpEdbInfoId.(float64))

	uniqueCode, ok := respData["UniqueCode"]
	if !ok {
		br.Msg = `数据转换异常`
		br.ErrMsg = fmt.Sprint("respData.UniqueCode 数据转换异常;respData:", respData)
		return
	}
	//添加es
	data.AddOrEditEdbInfoToEs(int(edbInfoId))

	//
	resp := data_manage.AddEdbInfoResp{
		EdbInfoId:  int(edbInfoId),
		UniqueCode: uniqueCode.(string),
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = resp
	br.IsAddLog = true
}

// BatchCalculateBatchSave
// @Title 批量添加 累计值转月-同比值-同差等计算新增
// @Description 批量添加 累计值转月-同比值-同差等计算新增接口
// @Param	request	body data_manage.EdbInfoCalculateBatchSaveReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/batch/save/batch [post]
func (this *ChartInfoController) BatchCalculateBatchSave() {
	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 data_manage.BatchEdbInfoCalculateBatchSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	resp := data_manage.BatchEdbInfoCalculateBatchSaveResp{
		Fail:    make([]data_manage.BatchEdbInfoCalculateBatchSaveFailResp, 0),
		Success: make([]data_manage.BatchEdbInfoCalculateBatchSaveSuccessResp, 0),
	}

	var formulaInt int
	switch req.Source {
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS, utils.DATA_SOURCE_CALCULATE_HBZ, utils.DATA_SOURCE_CALCULATE_HCZ, utils.DATA_SOURCE_CALCULATE_TIME_SHIFT, utils.DATA_SOURCE_CALCULATE_CJJX:
		if req.Formula == "" {
			br.Msg = "请输入N值"
			return
		}
		formulaInt, _ = strconv.Atoi(req.Formula)
		if formulaInt <= 0 {
			br.Msg = "N值输入错误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		//直接拼接指标
		//校验时间格式
		_, err = time.ParseInLocation(utils.FormatDate, req.Formula, time.Local)
		if err != nil {
			br.Msg = "拼接日期有误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_NHCC: //拟合残差指标
		//指标校验
		if len(req.EdbInfoIdArr) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}
		fromEdbInfoId := req.EdbInfoIdArr[0].EdbInfoId
		if fromEdbInfoId <= 0 {
			br.Msg = "请选择指标"
			return
		}
		//校验时间格式
		//数据格式：2022-11-01,2022-11-10
		timeList := strings.Split(req.Formula, ",")
		if len(timeList) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}
		startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
		if err != nil {
			br.Msg = "开始日期有误,请重新输入"
			return
		}
		endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
		if err != nil {
			br.Msg = "结束日期有误,请重新输入"
			return
		}
		if utils.GetTimeSubDay(startDate, endDate) < 2 {
			br.Msg = "日期间隔不得少于两天"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZSXY: // 指数修匀
		if req.Formula == "" {
			br.Msg = "请填写alpha值"
			return
		}
		alpha, e := strconv.ParseFloat(req.Formula, 64)
		if e != nil {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
		if alpha <= 0 || alpha >= 1 {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
	}

	if len(req.EdbList) > 100 {
		br.Msg = "最多只能选择100个指标"
		return
	}
	reqEdbList := make([]*data_manage.CalculateEdbInfoItem, 0)
	for _, v := range req.EdbList {
		v.EdbName = strings.Trim(v.EdbName, " ")
		if v.EdbName == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "指标名称不能为空",
			})
			continue
		}

		if v.Frequency == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "频率不能为空",
			})
			continue
		}

		if v.Unit == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "单位不能为空",
			})
			continue
		}

		if v.ClassifyId <= 0 {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "请选择分类",
			})
			continue
		}

		//加入缓存机制，避免创建同一个名称的指标 start
		redisKey := fmt.Sprint("edb_info:calculate:batch:save:", req.Source, ":", v.EdbName)
		isExist := utils.Rc.IsExist(redisKey)
		if isExist {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "指标正在处理,请勿重复提交",
			})
			continue
		} else {
			//设置3分钟缓存
			//utils.Rc.SetNX(redisKey, 1, time.Second*300)
			//redisKeyList = append(redisKeyList, redisKey)
		}
		reqEdbList = append(reqEdbList, v)
	}

	if len(reqEdbList) <= 0 {
		br.Msg = "新增失败！"
		if len(resp.Fail) > 0 {
			br.ErrMsg = resp.Fail[0].Msg
		} else {
			br.Msg = "请选择指标"
		}
		return
	}
	req.AdminId = sysUser.AdminId
	req.AdminName = sysUser.RealName
	req.EdbList = reqEdbList
	// 调用指标库去更新
	reqJson, err := json.Marshal(req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.BatchSaveEdbCalculateMultiData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "新增失败！"
		br.ErrMsg = "新增失败，Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "批量保存成功"
	br.Data = respItem.Data
	br.IsAddLog = true
}

// BatchCalculateBatchEdit
// @Title 多指标求和和多指标求平均编辑接口
// @Description 多指标求和和多指标求平均编辑接口
// @Param	request	body data_manage.EdbInfoCalculateBatchSaveReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/batch/edit/batch [post]
func (this *ChartInfoController) BatchCalculateBatchEdit() {
	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 data_manage.BatchEdbInfoCalculateBatchSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	resp := data_manage.BatchEdbInfoCalculateBatchSaveResp{
		Fail:    make([]data_manage.BatchEdbInfoCalculateBatchSaveFailResp, 0),
		Success: make([]data_manage.BatchEdbInfoCalculateBatchSaveSuccessResp, 0),
	}

	var formulaInt int
	switch req.Source {
	case utils.DATA_SOURCE_CALCULATE_NSZYDPJJS, utils.DATA_SOURCE_CALCULATE_HBZ, utils.DATA_SOURCE_CALCULATE_HCZ, utils.DATA_SOURCE_CALCULATE_TIME_SHIFT, utils.DATA_SOURCE_CALCULATE_CJJX:
		if req.Formula == "" {
			br.Msg = "请输入N值"
			return
		}
		formulaInt, _ = strconv.Atoi(req.Formula)
		if formulaInt <= 0 {
			br.Msg = "N值输入错误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZJPJ:
		//直接拼接指标
		//校验时间格式
		_, err = time.ParseInLocation(utils.FormatDate, req.Formula, time.Local)
		if err != nil {
			br.Msg = "拼接日期有误,请重新输入"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_NHCC: //拟合残差指标
		//指标校验
		if len(req.EdbInfoIdArr) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}
		fromEdbInfoId := req.EdbInfoIdArr[0].EdbInfoId
		if fromEdbInfoId <= 0 {
			br.Msg = "请选择指标"
			return
		}
		//校验时间格式
		//数据格式：2022-11-01,2022-11-10
		timeList := strings.Split(req.Formula, ",")
		if len(timeList) != 2 {
			br.Msg = "选择的指标异常,请重新选择"
			return
		}
		startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
		if err != nil {
			br.Msg = "开始日期有误,请重新输入"
			return
		}
		endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
		if err != nil {
			br.Msg = "结束日期有误,请重新输入"
			return
		}
		if utils.GetTimeSubDay(startDate, endDate) < 2 {
			br.Msg = "日期间隔不得少于两天"
			return
		}
	case utils.DATA_SOURCE_CALCULATE_ZSXY: // 指数修匀
		if req.Formula == "" {
			br.Msg = "请填写alpha值"
			return
		}
		alpha, e := strconv.ParseFloat(req.Formula, 64)
		if e != nil {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
		if alpha <= 0 || alpha >= 1 {
			br.Msg = "alpha值输入错误, 请重新输入"
			return
		}
	}

	if len(req.EdbList) > 50 {
		br.Msg = "最多只能选择50个指标"
		return
	}
	reqEdbList := make([]*data_manage.CalculateEdbInfoItem, 0)
	for _, v := range req.EdbList {
		if v.EdbInfoId <= 0 {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "请选择要编辑的指标",
			})
			continue
		}
		v.EdbName = strings.Trim(v.EdbName, " ")
		if v.EdbName == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "指标名称不能为空",
			})
			continue
		}

		if v.Frequency == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "频率不能为空",
			})
			continue
		}

		if v.Unit == "" {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "单位不能为空",
			})
			continue
		}

		if v.ClassifyId <= 0 {
			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
				CalculateId: v.CalculateId,
				Msg:         "请选择分类",
			})
			continue
		}

		reqEdbList = append(reqEdbList, v)
	}
	if len(reqEdbList) <= 0 {
		br.Msg = "编辑失败！"
		if len(resp.Fail) > 0 {
			br.ErrMsg = resp.Fail[0].Msg
		} else {
			br.Msg = "请选择指标"
		}
		return
	}
	req.EdbList = reqEdbList
	// 调用指标库去更新
	reqJson, err := json.Marshal(req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}
	respItem, err := data.BatchEditEdbCalculateMultiData(string(reqJson), this.Lang)
	if err != nil {
		br.Msg = "编辑失败！"
		br.ErrMsg = "编辑失败，Err:" + err.Error()
		return
	}
	if respItem.Ret != 200 {
		br.Msg = respItem.Msg
		br.ErrMsg = respItem.ErrMsg
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "批量编辑成功"
	br.Data = respItem.Data
	br.IsAddLog = true
}

// CalculateMapping
// @Title 获取计算指标与基础指标关联
// @Description 获取计算指标与基础指标关联
// @Param   EdbInfoId   query   int  true       "指标id"
// @Success 200 {object} data_manage.CalculateDetailResp
// @router /edb_info/calculate/mapping [get]
func (this *ChartInfoController) CalculateMapping() {
	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
	}
	edbInfoId, _ := this.GetInt("EdbInfoId")
	if edbInfoId <= 0 {
		br.Msg = "参数有误"
		return
	}
	item, e := data_manage.GetEdbInfoCalculateMappingDetail(edbInfoId)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败，Err:" + e.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "保存成功"
	br.Data = item
}

// CalculateComputeCorrelation
// @Title 拟合残差计算相关性
// @Description 拟合残差计算相关性接口
// @Param	request	body data_manage.EdbInfoCalculateBatchSaveReq true "type json string"
// @Success Ret=200 返回指标id
// @router /edb_info/calculate/compute_correlation [post]
func (this *ChartInfoController) CalculateComputeCorrelation() {
	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 data_manage.EdbInfoCalculateBatchSaveReq
	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
	if err != nil {
		br.Msg = "参数解析异常！"
		br.ErrMsg = "参数解析失败，Err:" + err.Error()
		return
	}

	if len(req.EdbInfoIdArr) != 2 {
		br.Msg = "选择的指标异常,请重新选择"
		return
	}
	fromEdbInfoId := req.EdbInfoIdArr[0].EdbInfoId

	//校验时间格式
	//数据格式：2022-11-01,2022-11-10
	timeList := strings.Split(req.Formula, ",")
	if len(timeList) != 2 {
		br.Msg = "选择时间有误,请重新输入"
		return
	}
	startDate, err := time.ParseInLocation(utils.FormatDate, timeList[0], time.Local)
	if err != nil {
		br.Msg = "开始日期有误,请重新输入"
		return
	}
	endDate, err := time.ParseInLocation(utils.FormatDate, timeList[1], time.Local)
	if err != nil {
		br.Msg = "结束日期有误,请重新输入"
		return
	}
	if utils.GetTimeSubDay(startDate, endDate) < 2 {
		br.Msg = "日期间隔不得少于两天"
		return
	}

	if fromEdbInfoId <= 0 {
		br.Msg = "请选择指标"
		return
	}

	req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
		AdminId:          sysUser.AdminId,
		AdminName:        sysUser.RealName,
		EdbInfoId:        req.EdbInfoId,
		EdbName:          req.EdbName,
		Frequency:        req.Frequency,
		Unit:             req.Unit,
		ClassifyId:       req.ClassifyId,
		Formula:          req.Formula, //N数值移动平均计算、环比值、环差值
		FromEdbInfoId:    req.FromEdbInfoId,
		CalculateFormula: req.CalculateFormula,
		Source:           req.Source,
		MoveType:         req.MoveType,
		MoveFrequency:    req.MoveFrequency,

		//CalculateFormula: edbInfo.CalculateFormula,
		EdbInfoIdArr: req.EdbInfoIdArr,
		Calendar:     req.Calendar,
	}

	val, err, errMsg := data.CallCalculateComputeCorrelation(req2, this.Lang)
	if err != nil {
		br.Msg = "计算失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = err.Error()
		return
	}
	br.Data = val

	br.Ret = 200
	br.Success = true
	br.Msg = "计算成功"
	br.IsAddLog = true
}

// CalculateMultiChoice
// @Title 批量计算-加入已选指标
// @Description 批量计算-加入已选指标
// @Param   ClassifyIds   query   int  true       "指标库分类IDs"
// @Param   SysUserIds   query   int  true       "创建人"
// @Param   Keyword   query   string  false       "关键词搜索"
// @Param   Frequency   query   string  false       "频度"
// @Success 200 {object} data_manage.EdbInfoSearchResp
// @router /edb_info/calculate/multi/choice [get]
func (this *ChartInfoController) CalculateMultiChoice() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	//来源类型，1：中文，2：英文
	frequency := this.GetString("Frequency")
	keyword := this.GetString("Keyword")
	sysUserIds := this.GetString("SysUserIds")
	classifyIds := this.GetString("ClassifyIds")
	edbInfoIds := this.GetString("EdbInfoIds")
	selectAll, _ := this.GetBool("SelectAll")
	notFrequency := this.GetString("NotFrequency")
	var edbIdArr []int

	if selectAll {
		// 如果勾了列表全选，那么EdbCode传的就是排除的code

		var condition string
		var pars []interface{}

		if classifyIds != "" {
			classifyIdsArr := strings.Split(classifyIds, ",")
			condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
			pars = append(pars, classifyIdsArr)
		}

		if frequency != "" {
			frequencyArr := strings.Split(frequency, ",")
			condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
			pars = append(pars, frequencyArr)
		}
		if notFrequency != "" {
			notFrequencyArr := strings.Split(notFrequency, ",")
			condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
			pars = append(pars, notFrequencyArr)
		}

		if sysUserIds != "" {
			sysUserIdSlice := strings.Split(sysUserIds, ",")
			condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
			pars = append(pars, sysUserIdSlice)
		}

		if keyword != "" {
			keyWordArr := strings.Split(keyword, " ")

			if len(keyWordArr) > 0 {
				for _, v := range keyWordArr {
					condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
					pars = append(pars, utils.GetLikeKeyword(v))
				}
			}
		}
		edbList, e := data_manage.GetEdbInfoFilter(condition, pars)
		if e != nil {
			br.Msg = "获取指标列表失败"
			br.ErrMsg = "获取指标列表失败，Err:" + e.Error()
			return
		}

		for _, v := range edbList {
			edbIdArr = append(edbIdArr, v.EdbInfoId)
		}
	} else {
		//未勾选全选EdbCode就是需要的code
		edbIdStrArr := strings.Split(edbInfoIds, ",")
		for _, v := range edbIdStrArr {
			id, e := strconv.Atoi(v)
			if e != nil {
				br.Msg = "获取指标列表失败"
				br.ErrMsg = "获取指标列表失败，Err:" + e.Error()
				return
			}
			edbIdArr = append(edbIdArr, id)
		}
	}

	if len(edbIdArr) > 100 {
		br.Msg = "最多只能选择100个指标"
		return
	}

	if len(edbIdArr) <= 0 {
		br.Msg = "无符合指标或指标代码错误"
		return
	}

	list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取指标列表失败"
		br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
		return
	}

	searchItemList := make([]data_manage.EdbInfoBase, 0)

	resp := new(data_manage.CalculateMultiChoiceResp)

	if len(list) > 0 {
		// 当前列表中的分类map
		classifyMap := make(map[int]*data_manage.EdbClassify)
		{
			classifyIdList := make([]int, 0)
			for _, info := range list {
				classifyIdList = append(classifyIdList, info.ClassifyId)
			}
			classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
			if err != nil {
				if err != nil {
					br.Msg = "获取失败"
					br.ErrMsg = "获取分类列表失败，Err:" + err.Error()
					return
				}
			}

			for _, v := range classifyList {
				classifyMap[v.ClassifyId] = v
			}
		}

		// 获取所有有权限的指标和分类
		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的指标和分类失败，Err:" + err.Error()
			return
		}
		for _, info := range list {
			var haveOperaAuth bool
			if currClassify, ok := classifyMap[info.ClassifyId]; ok {
				haveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(info.IsJoinPermission, currClassify.IsJoinPermission, info.EdbInfoId, info.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
			}
			searchItem := data_manage.EdbInfoBase{
				Frequency:     info.Frequency,
				Unit:          info.Unit,
				UnitEn:        info.UnitEn,
				EdbName:       info.EdbName,
				EdbNameEn:     info.EdbNameEn,
				EdbInfoId:     info.EdbInfoId,
				ClassifyId:    info.ClassifyId,
				HaveOperaAuth: haveOperaAuth,
			}
			searchItemList = append(searchItemList, searchItem)
		}
	}

	resp.SearchItem = searchItemList

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

// CalculateMultiSearch
// @Title 批量计算-查询指标
// @Description 批量计算-查询指标
// @Param   ClassifyIds   query   int  true       "指标库分类IDs"
// @Param   SysUserIds   query   int  true       "创建人"
// @Param   Keyword   query   string  false       "关键词搜索"
// @Param   Frequency   query   string  false       "频度"
// @Success 200 {object} data_manage.EdbInfoSearchResp
// @router /edb_info/calculate/multi/search [get]
func (this *ChartInfoController) CalculateMultiSearch() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	//来源类型，1：中文，2：英文
	frequency := this.GetString("Frequency")
	keyword := this.GetString("Keyword")
	sysUserIds := this.GetString("SysUserIds")
	classifyIds := this.GetString("ClassifyIds")

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	notFrequency := this.GetString("NotFrequency")

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

	var edbIdArr []int

	condition := ` AND edb_info_type = 0 `
	var pars []interface{}

	if classifyIds != "" {
		classifyIdsArr := strings.Split(classifyIds, ",")
		condition += ` AND classify_id IN (` + utils.GetOrmInReplace(len(classifyIdsArr)) + `) `
		pars = append(pars, classifyIdsArr)
	}

	if frequency != "" {
		frequencyArr := strings.Split(frequency, ",")
		condition += ` AND frequency IN (` + utils.GetOrmInReplace(len(frequencyArr)) + `) `
		pars = append(pars, frequencyArr)
	}
	if notFrequency != "" {
		notFrequencyArr := strings.Split(notFrequency, ",")
		condition += ` AND frequency NOT IN (` + utils.GetOrmInReplace(len(notFrequencyArr)) + `) `
		pars = append(pars, notFrequencyArr)
	}
	if sysUserIds != "" {
		sysUserIdSlice := strings.Split(sysUserIds, ",")
		condition += ` AND sys_user_id IN (` + utils.GetOrmInReplace(len(sysUserIdSlice)) + `)`
		pars = append(pars, sysUserIdSlice)
	}

	if keyword != "" {
		keyWordArr := strings.Split(keyword, " ")

		if len(keyWordArr) > 0 {
			for _, v := range keyWordArr {
				condition += ` AND CONCAT(edb_name,edb_code) LIKE ?`
				pars = append(pars, utils.GetLikeKeyword(v))
			}
		}
	}

	total, e := data_manage.GetEdbInfoByConditionCount(condition, pars)
	if e != nil {
		br.Msg = "获取指标列表总数失败"
		br.ErrMsg = "获取指标列表总数失败，Err:" + e.Error()
		return
	}

	searchItemList := make([]data_manage.CalculateMultiEdbSearchItem, 0)
	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := new(data_manage.CalculateMultiEdbSearchResp)

	edbList, e := data_manage.GetEdbInfoListByCondition(condition, pars, startSize, pageSize, "")
	if e != nil {
		br.Msg = "获取指标列表失败"
		br.ErrMsg = "获取指标列表失败，Err:" + e.Error()
		return
	}

	if len(edbList) > 0 {
		classifyIdList := make([]int, 0)
		for _, v := range edbList {
			edbIdArr = append(edbIdArr, v.EdbInfoId)
			classifyIdList = append(classifyIdList, v.ClassifyId)
		}

		// 当前列表中的分类map
		classifyMap := make(map[int]*data_manage.EdbClassify)
		{
			classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList)
			if err != nil {
				if err != nil {
					br.Msg = "获取失败"
					br.ErrMsg = "获取分类列表失败，Err:" + err.Error()
					return
				}
			}
			for _, v := range classifyList {
				classifyMap[v.ClassifyId] = v
			}
		}

		// 获取所有有权限的指标和分类
		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取所有有权限的指标和分类失败，Err:" + err.Error()
			return
		}

		list, err := data_manage.GetEdbInfoByIdList(edbIdArr)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "获取指标列表失败"
			br.ErrMsg = "获取指标列表失败,Err:" + err.Error()
			return
		}
		for _, info := range list {
			var haveOperaAuth bool
			if currClassify, ok := classifyMap[info.ClassifyId]; ok {
				haveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(info.IsJoinPermission, currClassify.IsJoinPermission, info.EdbInfoId, info.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
			}
			searchItem := data_manage.CalculateMultiEdbSearchItem{
				Frequency:       info.Frequency,
				Unit:            info.Unit,
				UnitEn:          info.UnitEn,
				EdbName:         info.EdbName,
				EdbNameEn:       info.EdbNameEn,
				EdbInfoId:       info.EdbInfoId,
				ClassifyId:      info.ClassifyId,
				SysUserRealName: info.SysUserRealName,
				SysUserId:       info.SysUserId,
				EndDate:         info.EndDate,
				EndValue:        info.EndValue,
				HaveOperaAuth:   haveOperaAuth,
			}
			searchItemList = append(searchItemList, searchItem)
		}
	}

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