package data_manage import ( "encoding/json" "eta_gn/eta_api/controllers" "eta_gn/eta_api/models" "eta_gn/eta_api/models/data_manage" "eta_gn/eta_api/services/data" "eta_gn/eta_api/services/data/data_manage_permission" "eta_gn/eta_api/utils" "fmt" "net/url" "strconv" "strings" "time" "github.com/rdlucklib/rdluck_tools/paging" ) // 计算指标 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 } // 日期转换 for _, v := range calculateList { v.ConvertToResp() } fullEdb := new(data_manage.EdbInfoFullClassify) classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfo.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = errMsg return } edbInfoResp, err := edbInfo.ConvertToResp() if err != nil { br.Msg = err.Error() br.ErrMsg = errMsg return } fullEdb.EdbInfoResp = edbInfoResp 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, EmptyType: req.EmptyType, } // 调用指标库去更新 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 utils.IsErrNoRow(err) { 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, AdminId: this.SysUser.AdminId, AdminName: this.SysUser.RealName, 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, EmptyType: req.EmptyType, } // 调用指标库去更新 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 utils.IsErrNoRow(err) { 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 utils.IsErrNoRow(err) { // 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 } // 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 utils.IsErrNoRow(err) { 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 && utils.UseMongo { 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.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.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 } // 英文来源,显示英文名称 if this.Lang == utils.EnLangVersion { fromEdbInfo, e := data_manage.GetEdbInfoById(item.FromEdbInfoId) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + e.Error() return } item.FromEdbName = fromEdbInfo.EdbNameEn } 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 "频度" // @Param EdbInfoType query int false "指标类型: 0-普通指标; 1-预测指标" // @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") edbInfoType, _ := this.GetInt("EdbInfoType", 0) var edbIdArr []int var filterEdbIds []int if edbInfoIds != "" { arr := strings.Split(edbInfoIds, ",") for _, v := range arr { t, e := strconv.Atoi(v) if e != nil { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("指标ID有误, %s", v) return } filterEdbIds = append(filterEdbIds, t) } } if selectAll { // 如果勾了列表全选,那么EdbCode传的就是排除的code condition := ` AND edb_info_type = ? ` pars := make([]interface{}, 0) pars = append(pars, edbInfoType) 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.GetEdbInfoListByCond(condition, pars) if e != nil { br.Msg = "获取指标列表失败" br.ErrMsg = "获取指标列表失败,Err:" + e.Error() return } filterLen := len(filterEdbIds) for _, v := range edbList { // 全选-排除传入的指标 if filterLen > 0 && utils.InArrayByInt(filterEdbIds, v.EdbInfoId) { continue } 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 && !utils.IsErrNoRow(err) { 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, EdbInfoType: info.EdbInfoType, } 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 "频度" // @Param EdbInfoType query int false "指标类型: 0-普通指标; 1-预测指标" // @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") edbInfoType, _ := this.GetInt("EdbInfoType", 0) 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 = ? ` pars := make([]interface{}, 0) pars = append(pars, edbInfoType) 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 && !utils.IsErrNoRow(err) { 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: utils.TimeToFormatDate(info.EndDate), EndValue: info.EndValue, HaveOperaAuth: haveOperaAuth, EdbInfoType: info.EdbInfoType, } searchItemList = append(searchItemList, searchItem) } } resp.SearchItem = searchItemList resp.Paging = page br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp }