package data_manage import ( "encoding/json" "eta/eta_api/controllers" "eta/eta_api/models" "eta/eta_api/models/data_manage" "eta/eta_api/models/data_manage/request" "eta/eta_api/models/data_manage/response" "eta/eta_api/services" "eta/eta_api/services/data" "eta/eta_api/services/data/data_manage_permission" "eta/eta_api/services/elastic" "eta/eta_api/utils" "fmt" "sort" "strconv" "strings" "time" "github.com/rdlucklib/rdluck_tools/paging" "github.com/shopspring/decimal" ) // PredictEdbInfoController 预测指标 type PredictEdbInfoController struct { controllers.BaseAuthController } // EdbChartList // @Title 预测指标列表接口 // @Description 预测指标列表接口 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param ClassifyId query int true "分类id" // @Param AdminId query int false "创建人id" // @Param IsOnlyMe query bool false "是否只看我的" // @Success 200 {object} response.PredictEdbInfoListResp // @router /predict_edb_info/chart/list [get] func (this *PredictEdbInfoController) EdbChartList() { 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 } classifyId, _ := this.GetInt("ClassifyId") pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") adminId, _ := this.GetInt("AdminId") isOnlyMe, _ := this.GetBool("IsOnlyMe") var total int page := paging.GetPaging(currentIndex, pageSize, total) var startSize int if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) var condition string var pars []interface{} // 预测指标 condition += ` AND edb_info_type = ? ` pars = append(pars, 1) // 筛选分类 if classifyId > 0 { childClassify, e, _ := data.GetChildClassifyByClassifyId(classifyId) if e != nil && e.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取分类信息失败, GetEdbClassify,Err:" + e.Error() return } var classifyIds []int for _, v := range childClassify { classifyIds = append(classifyIds, v.ClassifyId) } condition += fmt.Sprintf(` AND classify_id IN (%s) `, utils.GetOrmInReplace(len(classifyIds))) pars = append(pars, classifyIds) } if adminId > 0 { condition += " AND sys_user_id = ? " pars = append(pars, adminId) } if isOnlyMe { condition += " AND sys_user_id = ? " pars = append(pars, sysUser.AdminId) } // 获取当前账号的不可见指标 obj := data_manage.EdbInfoNoPermissionAdmin{} confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error() return } noPermissionEdbInfoIdList := make([]int, 0) for _, v := range confList { noPermissionEdbInfoIdList = append(noPermissionEdbInfoIdList, v.EdbInfoId) } noPermissionEdbInfoIdNum := len(noPermissionEdbInfoIdList) if noPermissionEdbInfoIdNum > 0 { condition += ` AND edb_info_id not in (` + utils.GetOrmInReplace(noPermissionEdbInfoIdNum) + `) ` pars = append(pars, noPermissionEdbInfoIdList) } //获取指标信息 dataCount, list, err := data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize) if err != nil && err.Error() != utils.ErrNoRow() { br.Success = true br.Msg = "获取预测指标列表失败" br.ErrMsg = "获取预测指标列表失败,Err:" + err.Error() return } if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) { list = make([]*data_manage.EdbInfoList, 0) } else { classifyIdList := make([]int, 0) for _, v := range list { classifyIdList = append(classifyIdList, v.ClassifyId) } // 指标权限 { // 当前的分类 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 } for _, v := range list { if currClassify, ok := classifyMap[v.ClassifyId]; ok { v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, currClassify.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList) v.Button = data.GetEdbOpButton(sysUser, v.SysUserId, v.EdbType, v.EdbInfoType, v.HaveOperaAuth) } } } page = paging.GetPaging(currentIndex, pageSize, int(dataCount)) } resp := response.PredictEdbInfoListResp{ Paging: page, List: list, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // List // @Title 指标数据列表接口 // @Description 指标数据列表接口 // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Param EdbInfoId query int true "指标id" // @Param KeyWord query string false "搜索关键词:指标ID/指标名称" // @Success 200 {object} data_manage.EdbInfoListResp // @router /predict_edb_info/list [get] func (this *PredictEdbInfoController) List() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() edbInfoId, _ := this.GetInt("EdbInfoId") keyWord := this.GetString("KeyWord") pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") var total int page := paging.GetPaging(currentIndex, pageSize, total) var startSize int if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) var condition string var pars []interface{} // 指标类型,0:普通指标,1:预测指标 condition += " AND edb_info_type=? " pars = append(pars, 1) if edbInfoId > 0 { condition += " AND edb_info_id=? " pars = append(pars, edbInfoId) } if keyWord != "" { condition += ` AND ( edb_code LIKE '%` + keyWord + `%' OR edb_name LIKE '%` + keyWord + `%' )` //pars = append(pars, keyWord) //pars = append(pars, keyWord) } resp := data_manage.EdbInfoListResp{} if condition == "" { item := new(data_manage.EdbInfoList) resp.Paging = page resp.Item = item br.Ret = 200 br.Success = true br.Msg = "获取成功" return } //获取指标信息 edbInfoItem, err := data_manage.GetEdbInfoByCondition(condition, pars) if err != nil && err.Error() != utils.ErrNoRow() { br.Success = true br.Msg = "获取指标信息失败" br.ErrMsg = "获取指标信息失败,Err:" + err.Error() return } if edbInfoItem == nil || (err != nil && err.Error() == utils.ErrNoRow()) { item := new(data_manage.EdbInfoList) resp.Paging = page resp.Item = item br.Ret = 200 br.Success = true br.Msg = "获取成功" return } //获取英文频度 edbInfoItem.FrequencyEn = data.GetFrequencyEn(edbInfoItem.Frequency) // 未来的指标预测数据 predictDataList := make([]*data_manage.EdbData, 0) var existCondition string var existPars []interface{} existCondition += " AND edb_info_id=? " existPars = append(existPars, edbInfoId) //查询出所有的关联指标 sourceEdbInfoCalculateMappingList, err := data_manage.GetEdbInfoCalculateListByCondition(existCondition, existPars) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取预测指标关联信息失败,Err:" + err.Error() return } if len(sourceEdbInfoCalculateMappingList) <= 0 { br.Msg = "获取失败" br.ErrMsg = "查找预测指标关联信息失败" return } //获取指标数据(实际已生成) { dataCount, dataList, err := data.GetPageData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate, startSize, pageSize) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取指标信息失败" br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error() return } page = paging.GetPaging(currentIndex, pageSize, dataCount) edbInfoItem.DataList = dataList } // 第一页才需要 获取预测指标未来的数据 if currentIndex == 1 { predictDataList, err = data_manage.GetAllEdbDataListData(edbInfoItem.EdbInfoId, edbInfoItem.Source, edbInfoItem.SubSource, edbInfoItem.LatestDate) if err != nil { br.Msg = "获取指标信息失败" br.ErrMsg = "获取指标数据失败,Err:" + err.Error() return } if err != nil { br.Msg = "获取预测指标数据失败" br.ErrMsg = "获取预测指标数据失败" + err.Error() return } } // 如果预测数据没有,那么返回空数组 if predictDataList == nil { predictDataList = make([]*data_manage.EdbData, 0) } edbInfoItem.PredictDataList = predictDataList // 如果实际数据没有,那么返回空数组 if edbInfoItem.DataList == nil { edbInfoItem.DataList = make([]*data_manage.EdbData, 0) } //查询目录 classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfoItem.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = errMsg return } // 权限校验 { classifyMap := make(map[int]*data_manage.EdbClassifyIdItems) for _, v := range classifyList { classifyMap[v.ClassifyId] = v } if currClassify, ok := classifyMap[edbInfoItem.ClassifyId]; ok { haveOperaAuth, err := data_manage_permission.CheckEdbPermission(edbInfoItem.IsJoinPermission, currClassify.IsJoinPermission, this.SysUser.AdminId, edbInfoItem.EdbInfoId, edbInfoItem.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = "校验指标权限失败,err:" + err.Error() return } edbInfoItem.HaveOperaAuth = haveOperaAuth } } resp.Paging = page resp.Item = edbInfoItem resp.ClassifyList = classifyList br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Add // @Title 新增指标接口 // @Description 新增指标接口 // @Param request body request.AddPredictEdbInfoReq true "type json string" // @Success 200 {object} response.AddEdbInfoResp // @router /predict_edb_info/add [post] func (this *PredictEdbInfoController) Add() { 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 } deleteCache := true cacheKey := "CACHE_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId) defer func() { if deleteCache { utils.Rc.Delete(cacheKey) } }() if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) { deleteCache = false br.Msg = "系统处理中,请稍后重试!" br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody) return } var req request.AddPredictEdbInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } sourceEdbInfoId := req.SourceEdbInfoId if sourceEdbInfoId <= 0 { br.Msg = "请选择来源指标" br.IsSendEmail = false return } if req.EdbName == "" { br.Msg = "指标名称不能为空" br.IsSendEmail = false return } if req.ClassifyId <= 0 { br.Msg = "请选择分类" br.IsSendEmail = false return } if len(req.RuleList) <= 0 { br.Msg = "请填写预测规则" br.IsSendEmail = false return } // 根据截止日期重新排序 ruleList := make([]request.RuleConfig, 0) { ruleMap := make(map[string]request.RuleConfig) ruleEndNumSortMap := make(map[int]request.RuleConfig) dateIntList := make([]int64, 0) endNumList := make([]int, 0) for _, v := range req.RuleList { if req.EndDateType == 0 { confEndDate, err := time.Parse(utils.FormatDate, v.EndDate) if err != nil { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error() br.IsSendEmail = false return } dateIntList = append(dateIntList, confEndDate.Unix()) ruleMap[v.EndDate] = v } else { if _, ok := ruleEndNumSortMap[v.EndNum]; ok { br.Msg = "所选期数不能和其他时间段相同" return } endNumList = append(endNumList, v.EndNum) ruleEndNumSortMap[v.EndNum] = v } } if req.EndDateType == 0 { sort.Slice(dateIntList, func(i, j int) bool { return dateIntList[i] < dateIntList[j] }) for _, dateInt := range dateIntList { currDateTime := time.Unix(dateInt, 0) item, ok := ruleMap[currDateTime.Format(utils.FormatDate)] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } else { sort.Ints(endNumList) for _, endNum := range endNumList { item, ok := ruleEndNumSortMap[endNum] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } } req.RuleList = ruleList //传入操作人 req.AdminId = sysUser.AdminId req.AdminName = sysUser.RealName // 添加计算指标 reqJson, err := json.Marshal(req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } respItem, err := data.SaveBasePredictEdbData(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 edbInfoIdArr := make([]int, 0) //查询相关的指标 edbMappingList, err := data_manage.GetAllCalculateByEdbInfoIdV2(resp.EdbInfoId) if err != nil { br.Msg = "操作失败" br.ErrMsg = "获取引用的指标信息失败,Err:" + err.Error() return } for _, v := range edbMappingList { edbInfoIdArr = append(edbInfoIdArr, v.FromEdbInfoId) } // 添加指标引用记录 _ = data.SavePredictEdbInfoRelation(edbInfoIdArr, resp.EdbInfoId) //添加es data.AddOrEditEdbInfoToEs(resp.EdbInfoId) br.Ret = 200 br.Success = true br.Msg = "保存成功" br.Data = resp br.IsAddLog = true } // ChartImageSet // @Title 设置指标的图表图片 // @Description 设置指标的图表图片接口 // @Param request body data_manage.SetChartInfoImageReq true "type json string" // @Success Ret=200 保存成功 // @router /predict_edb_info/image/set [post] func (this *PredictEdbInfoController) ChartImageSet() { 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.SetEdbInfoImageReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } if req.EdbInfoId > 0 && req.ImageUrl != "" { edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId) if err != nil { br.Msg = "保存失败" br.ErrMsg = "保存失败,Err:" + err.Error() if err.Error() == utils.ErrNoRow() { br.Msg = "找不到该指标" br.ErrMsg = "找不到该指标" br.IsSendEmail = false } return } edbInfo.ChartImage = req.ImageUrl err = edbInfo.Update([]string{"ChartImage"}) if err != nil { br.Msg = "保存失败" br.ErrMsg = "保存失败,Err:" + err.Error() return } //修改es数据 go data.AddOrEditEdbInfoToEs(req.EdbInfoId) } br.Ret = 200 br.Success = true br.Msg = "保存成功" } // Edit // @Title 编辑指标接口 // @Description 编辑指标接口 // @Success 200 {object} request.EditEdbInfoReq // @router /predict_edb_info/edit [post] func (this *PredictEdbInfoController) Edit() { 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 request.AddPredictEdbInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } edbInfoId := req.EdbInfoId if edbInfoId <= 0 { br.Msg = "请选择预测指标" br.IsSendEmail = false return } if req.EdbName == "" { br.Msg = "指标名称不能为空" br.IsSendEmail = false return } if req.ClassifyId <= 0 { br.Msg = "请选择分类" br.IsSendEmail = false return } if len(req.RuleList) <= 0 { br.Msg = "请填写预测规则" br.IsSendEmail = false return } // 根据截止日期重新排序 ruleList := make([]request.RuleConfig, 0) { ruleMap := make(map[string]request.RuleConfig) ruleEndNumSortMap := make(map[int]request.RuleConfig) dateIntList := make([]int64, 0) endNumList := make([]int, 0) for _, v := range req.RuleList { if req.EndDateType == 0 { confEndDate, err := time.Parse(utils.FormatDate, v.EndDate) if err != nil { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error() br.IsSendEmail = false return } dateIntList = append(dateIntList, confEndDate.Unix()) ruleMap[v.EndDate] = v } else { if _, ok := ruleEndNumSortMap[v.EndNum]; ok { br.Msg = "所选期数不能和其他时间段相同" return } endNumList = append(endNumList, v.EndNum) ruleEndNumSortMap[v.EndNum] = v } } if req.EndDateType == 0 { sort.Slice(dateIntList, func(i, j int) bool { return dateIntList[i] < dateIntList[j] }) for _, dateInt := range dateIntList { currDateTime := time.Unix(dateInt, 0) item, ok := ruleMap[currDateTime.Format(utils.FormatDate)] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } else { sort.Ints(endNumList) for _, endNum := range endNumList { item, ok := ruleEndNumSortMap[endNum] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } } req.RuleList = ruleList edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId) if err != nil { br.Msg = "修改失败" br.ErrMsg = "获取指标信息失败,Err:" + err.Error() return } var haveOperaAuth bool // 数据权限校验 { haveOperaAuth, err = data_manage_permission.CheckEdbPermissionByEdbInfoId(edbInfo.EdbInfoId, edbInfo.ClassifyId, edbInfo.IsJoinPermission, this.SysUser.AdminId) if err != nil { br.Msg = err.Error() br.ErrMsg = "校验指标权限失败,err:" + err.Error() return } } // 编辑权限校验 button := data.GetPredictEdbOpButton(this.SysUser, edbInfo.SysUserId, haveOperaAuth) if !button.OpButton { br.Msg = "无权限操作" br.IsSendEmail = false 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 } respItem, err := data.SaveBasePredictEdbData(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 edbInfoIdArr := make([]int, 0) //查询相关的指标 edbMappingList, err := data_manage.GetAllCalculateByEdbInfoIdV2(resp.EdbInfoId) if err != nil { br.Msg = "操作失败" br.ErrMsg = "获取引用的指标信息失败,Err:" + err.Error() return } for _, v := range edbMappingList { edbInfoIdArr = append(edbInfoIdArr, v.FromEdbInfoId) } // 添加指标引用记录 _ = data.SavePredictEdbInfoRelation(edbInfoIdArr, resp.EdbInfoId) //修改es data.AddOrEditEdbInfoToEs(resp.EdbInfoId) // 添加操作日志 newEdbRecord := new(data_manage.EdbInfoEditRecord) newEdbRecord.EdbName = req.EdbName // 频度和单位在此接口不处理 newEdbRecord.Frequency = edbInfo.Frequency newEdbRecord.Unit = edbInfo.Unit newEdbRecord.OperateUserId = sysUser.AdminId newEdbRecord.OperateUserRealName = sysUser.RealName go data.AddEditEdbInfoRcord(edbInfo, newEdbRecord) // 刷新关联指标 go data.EdbInfoRefreshAllFromBaseV2(resp.EdbInfoId, true, false) br.Ret = 200 br.Success = true br.Msg = "修改成功" br.IsAddLog = true } // Refresh // @Title 指标刷新接口 // @Description 指标刷新接口 // @Param EdbInfoId query int true "指标id" // @Success Ret=200 刷新成功 // @router /predict_edb_info/refresh [get] func (this *PredictEdbInfoController) Refresh() { 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 = "参数错误" br.ErrMsg = "参数错误" return } _, isAsync, err, errMsg := data.RefreshPredictEdbInfo(edbInfoId, false) if errMsg != `` { br.Msg = errMsg br.ErrMsg = errMsg if err != nil { br.ErrMsg = err.Error() } else { br.IsSendEmail = false } return } br.Ret = 200 br.Success = true br.Msg = "刷新成功" if isAsync { br.Msg = "该指标关联指标较多,请10分钟后刷新页面查看最新数据" } } // Move // @Title 移动指标接口 // @Description 移动指标接口 // @Success 200 {object} data_manage.MoveEdbInfoReq // @router /predict_edb_info/move [post] func (this *PredictEdbInfoController) Move() { 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.MoveEdbInfoReq 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小于等于0" return } if req.ClassifyId <= 0 { br.Msg = "请选择分类" return } // 移动预测指标 err, errMsg := data.MovePredictEdbInfo(req.EdbInfoId, req.ClassifyId, req.PrevEdbInfoId, req.NextEdbInfoId, sysUser, string(this.Ctx.Input.RequestBody), this.Ctx.Input.URI()) if errMsg != `` { br.Msg = errMsg br.ErrMsg = errMsg if err != nil { br.ErrMsg = errMsg + ";Err:" + err.Error() } else { br.IsSendEmail = false } return } br.Ret = 200 br.Success = true br.Msg = "移动成功" } // Detail // @Title 获取指标详情 // @Description 获取指标详情接口 // @Param EdbInfoId query int true "指标id" // @Success 200 {object} response.PredictEdbInfo // @router /predict_edb_info/detail [get] func (this *PredictEdbInfoController) Detail() { 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 = "参数错误" br.ErrMsg = "参数错误" return } edbInfo, err := data_manage.GetEdbInfoById(edbInfoId) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取指标信息失败,Err:" + err.Error() return } var ruleType int var fixedValue float64 calculateList := make([]*data_manage.EdbInfoCalculateDetail, 0) predictEdbConfList := make([]data_manage.PredictEdbConfDetail, 0) calculateList, err = data_manage.GetEdbInfoCalculateDetail(edbInfoId, edbInfo.Source) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + err.Error() return } if edbInfo.EdbType == 1 { // 获取所有的指标预测规则配置 tmpPredictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfoId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取预测指标配置信息失败,Err:" + err.Error() return } for _, v := range tmpPredictEdbConfList { var tmpPredictEdbConfCalculateMappingDetail []*data_manage.PredictEdbConfCalculateMappingDetail if v.RuleType == 9 || v.RuleType == 14 { tmpPredictEdbConfCalculateMappingDetail, err = data_manage.GetPredictEdbConfCalculateMappingDetailListByConfigId(v.PredictEdbInfoId, v.ConfigId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error() return } } if len(tmpPredictEdbConfCalculateMappingDetail) <= 0 { tmpPredictEdbConfCalculateMappingDetail = make([]*data_manage.PredictEdbConfCalculateMappingDetail, 0) } if v.RuleType == 16 { if !strings.Contains(v.Value, "YearList") { // 解析json串,加入YearList字段重新生成json字符串 var tmpValue *data.AnnualValueInversionConf err = json.Unmarshal([]byte(v.Value), &tmpValue) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error() return } tmpValue.YearList = append(tmpValue.YearList, tmpValue.Year) tmpValueByte, err := json.Marshal(tmpValue) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取预测指标配置与关联指标信息失败,Err:" + err.Error() return } v.Value = string(tmpValueByte) } } tmp := data_manage.PredictEdbConfDetail{ ConfigId: v.ConfigId, PredictEdbInfoId: v.PredictEdbInfoId, SourceEdbInfoId: v.SourceEdbInfoId, RuleType: v.RuleType, FixedValue: v.FixedValue, Value: v.Value, EmptyType: v.EmptyType, MaxEmptyType: v.MaxEmptyType, EndDate: v.EndDate, ModifyTime: v.ModifyTime, CreateTime: v.CreateTime, CalculateList: tmpPredictEdbConfCalculateMappingDetail, EndNum: v.EndNum, } predictEdbConfList = append(predictEdbConfList, tmp) } //calculateList, err = data_manage.GetEdbInfoCalculateDetail(edbInfoId, edbInfo.Source) //if err != nil { // br.Msg = "获取失败" // br.ErrMsg = "获取失败,Err:" + err.Error() // return //} if len(predictEdbConfList) == 0 { br.Msg = "找不到该预测指标配置" br.ErrMsg = "找不到该预测指标配置" return } predictEdbConf := predictEdbConfList[0] ruleType = predictEdbConf.RuleType fixedValue = predictEdbConf.FixedValue } findEdbInfoIdList := make([]int, 0) for k, v := range calculateList { if v.LatestDate != v.EndDate && v.LatestDate != `` && v.EndDate != `` { tmpLatestDate, _ := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local) tmpEndDate, _ := time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local) if tmpEndDate.After(tmpLatestDate) { findEdbInfoIdList = append(findEdbInfoIdList, v.FromEdbInfoId) } } v.EndValue = v.LatestValue calculateList[k] = v } if len(findEdbInfoIdList) > 0 { edbDataInsertConfigList, err := data_manage.GetEdbDataInsertConfigByEdbIdList(findEdbInfoIdList) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败插入值失败,Err:" + err.Error() return } edbDataInsertConfigMap := make(map[int]*data_manage.EdbDataInsertConfig) for _, v := range edbDataInsertConfigList { edbDataInsertConfigMap[v.EdbInfoId] = v } for k, v := range calculateList { edbDataInsertConfig, ok := edbDataInsertConfigMap[v.FromEdbInfoId] if !ok { continue } if v.EndDate != `` && v.EndDate == edbDataInsertConfig.Date.Format(utils.FormatDate) { t, tmpErr := decimal.NewFromString(edbDataInsertConfig.Value) if tmpErr != nil { continue } v.EndValue, _ = t.Float64() } calculateList[k] = v } } classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfo.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = errMsg return } edbInfoFull := new(response.EdbInfoFull) edbInfoFull.EdbInfo = edbInfo // 权限校验 { classifyMap := make(map[int]*data_manage.EdbClassifyIdItems) for _, v := range classifyList { classifyMap[v.ClassifyId] = v } if currClassify, ok := classifyMap[edbInfo.ClassifyId]; ok { haveOperaAuth, err := data_manage_permission.CheckEdbPermission(edbInfo.IsJoinPermission, currClassify.IsJoinPermission, this.SysUser.AdminId, edbInfo.EdbInfoId, edbInfo.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = "校验指标权限失败,err:" + err.Error() return } edbInfoFull.HaveOperaAuth = haveOperaAuth } } // 拟合残差计算相关系数 var correlationStr string if edbInfo.Source == utils.DATA_SOURCE_PREDICT_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 { correlationStr = val } } } resp := response.PredictEdbInfo{ EdbInfoFull: edbInfoFull, RuleType: ruleType, FixedValue: fixedValue, CalculateList: calculateList, RuleList: predictEdbConfList, CorrelationStr: correlationStr, ClassifyList: classifyList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // FilterByEs // @Title 指标筛选接口 // @Description 指标筛选接口 // @Param KeyWord query string false "搜索关键词:指标ID/指标名称" // @Param FilterSource query int false "搜索来源:1:其他搜索,2:累计值转月值搜索,3:变频,4:基础指标,5:同比" // @Param Frequency query string false "频度" // @Param IsOnlyMe query bool false "是否只看我的" // @Param PageSize query int true "每页数据条数" // @Param CurrentIndex query int true "当前页页码,从1开始" // @Success 200 {object} data_manage.EdbInfoList // @router /predict_edb_info/filter_by_es [get] func (this *PredictEdbInfoController) FilterByEs() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() pageSize, _ := this.GetInt("PageSize") currentIndex, _ := this.GetInt("CurrentIndex") var total int64 var startSize int if pageSize <= 0 { pageSize = utils.PageSize20 } if currentIndex <= 0 { currentIndex = 1 } startSize = paging.StartIndex(currentIndex, pageSize) keyWord := this.GetString("Keyword") keyWord = strings.TrimSpace(keyWord) //移除字符串首尾空格 //兼容前端 if keyWord == `` { keyWord = this.GetString("KeyWord") keyWord = strings.TrimSpace(keyWord) //移除字符串首尾空格 } filterSource, _ := this.GetInt("FilterSource") if filterSource <= 0 { filterSource = 1 } //指标来源 source, _ := this.GetInt("Source") frequency := this.GetString("Frequency") //频度 isOnlyMe, _ := this.GetBool("IsOnlyMe") var edbInfoList []*data_manage.EdbInfoList var err error noPermissionEdbInfoIdList := make([]int, 0) //无权限指标 // 获取当前账号的不可见指标 { obj := data_manage.EdbInfoNoPermissionAdmin{} confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error() return } for _, v := range confList { noPermissionEdbInfoIdList = append(noPermissionEdbInfoIdList, v.EdbInfoId) } } // 是否走ES isEs := false if keyWord != "" { var keyWordArr []string keyWordArr = append(keyWordArr, keyWord) newKeyWord := strings.Split(keyWord, " ") keyWordArr = append(keyWordArr, newKeyWord...) if isOnlyMe { total, edbInfoList, err = elastic.SearchEdbInfoDataByAdminId(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, this.SysUser.AdminId) } else { total, edbInfoList, err = elastic.SearchEdbInfoData(utils.DATA_INDEX_NAME, keyWord, startSize, pageSize, filterSource, source, 1, frequency, noPermissionEdbInfoIdList) } isEs = true } else { var condition string var pars []interface{} // 预测指标 condition += ` AND edb_info_type = ? ` pars = append(pars, 1) // 无权限指标id lenNoPermissionEdbInfoIdList := len(noPermissionEdbInfoIdList) if lenNoPermissionEdbInfoIdList > 0 { condition += ` AND edb_info_id not in (` + utils.GetOrmInReplace(lenNoPermissionEdbInfoIdList) + `) ` pars = append(pars, noPermissionEdbInfoIdList) } switch filterSource { case 2: condition += ` AND frequency='月度' ` case 3: condition += ` AND frequency <> '日度' ` case 4: condition += ` AND edb_type = 1 ` case 5: condition += ` AND source = 32 ` //来源(预测同比值) case 6: condition += ` AND frequency != ? ` pars = append(pars, "年度") } //频度 if frequency != "" { condition += ` AND frequency = ? ` pars = append(pars, frequency) } if isOnlyMe { condition += " AND sys_user_id = ? " pars = append(pars, this.SysUser.AdminId) } total, edbInfoList, err = data_manage.GetEdbInfoFilterList(condition, pars, startSize, pageSize) } if err != nil { edbInfoList = make([]*data_manage.EdbInfoList, 0) } page := paging.GetPaging(currentIndex, pageSize, int(total)) edbInfoListLen := len(edbInfoList) classifyIdList := make([]int, 0) for i := 0; i < edbInfoListLen; i++ { edbInfoList[i].EdbNameAlias = edbInfoList[i].EdbName classifyIdList = append(classifyIdList, edbInfoList[i].ClassifyId) } // 当前列表中的分类map classifyMap := make(map[int]*data_manage.EdbClassify) if edbInfoListLen > 0 { classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList) 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 } // 如果是ES的话,需要重新查一下指标的信息,主要是为了把是否授权字段找出来 if isEs { edbInfoIdList := make([]int, 0) for i := 0; i < edbInfoListLen; i++ { edbInfoIdList = append(edbInfoIdList, edbInfoList[i].EdbInfoId) tmpEdbInfo := edbInfoList[i] if currClassify, ok := classifyMap[tmpEdbInfo.ClassifyId]; ok { edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfo.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfo.EdbInfoId, tmpEdbInfo.ClassifyId, permissionEdbIdList, permissionClassifyIdList) } } tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取所有有权限的指标和分类失败,Err:" + err.Error() return } edbInfoMap := make(map[int]*data_manage.EdbInfo) for _, v := range tmpEdbList { edbInfoMap[v.EdbInfoId] = v } for i := 0; i < edbInfoListLen; i++ { tmpEdbInfo, ok := edbInfoMap[edbInfoList[i].EdbInfoId] if !ok { continue } edbInfoList[i].IsJoinPermission = tmpEdbInfo.IsJoinPermission } } // 权限校验 for i := 0; i < edbInfoListLen; i++ { tmpEdbInfo := edbInfoList[i] if currClassify, ok := classifyMap[tmpEdbInfo.ClassifyId]; ok { edbInfoList[i].HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(tmpEdbInfo.IsJoinPermission, currClassify.IsJoinPermission, tmpEdbInfo.EdbInfoId, tmpEdbInfo.ClassifyId, permissionEdbIdList, permissionClassifyIdList) } } } for i := 0; i < edbInfoListLen; i++ { for j := 0; j < edbInfoListLen; j++ { if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) && (edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) && !(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) { edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")" } } } //新增搜索词记录 { searchKeyword := new(data_manage.SearchKeyword) searchKeyword.KeyWord = keyWord searchKeyword.CreateTime = time.Now() go data_manage.AddSearchKeyword(searchKeyword) } resp := data_manage.EdbInfoFilterDataResp{ Paging: page, List: edbInfoList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // RefreshAll // @Title 指标全部刷新接口 // @Description 指标全部刷新接口 // @Param EdbInfoId query int true "指标id" // @Success Ret=200 全部刷新成功 // @router /predict_edb_info/refresh/all [get] func (this *PredictEdbInfoController) RefreshAll() { 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 = "参数错误" br.ErrMsg = "参数错误" return } _, isAsync, err, errMsg := data.RefreshPredictEdbInfo(edbInfoId, true) if errMsg != `` { br.Msg = errMsg br.ErrMsg = errMsg if err != nil { br.ErrMsg = err.Error() } else { br.IsSendEmail = false } return } br.Ret = 200 br.Success = true br.Msg = "刷新成功" if isAsync { br.Msg = "该指标关联指标较多,请10分钟后刷新页面查看最新数据" } } // DataList // @Title 获取指标数据 // @Description 获取指标数据 // @Param EdbInfoId query int true "指标ID" // @Param DateType query int true "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间,6:自定义起始时间至今,7:18年至今,8:19年至今,9:20年至今,10:全部" // @Param StartDate query string true "自定义开始日期" // @Param EndDate query string true "自定义结束日期" // @Param Calendar query string true "公历/农历" // @Param SeasonStartDate query string true "季节性图开始日期" // @Param SeasonEndDate query string true "季节性图结束日期" // @Param ChartType query int true "生成样式:1:曲线图,2:季节性图" // @Success 200 {object} data_manage.EdbInfoDataResp // @router /predict_edb_info/data [get] func (this *PredictEdbInfoController) DataList() { 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 } dateType, _ := this.GetInt("DateType") if dateType <= 0 { dateType = 3 } edbInfoType, _ := this.GetInt("EdbInfoType") if edbInfoType < 0 { edbInfoType = 1 } startDate := this.GetString("StartDate") endDate := this.GetString("EndDate") startYear, _ := this.GetInt("StartYear") chartType, _ := this.GetInt("ChartType") if chartType <= 0 { chartType = 1 } calendar := this.GetString("Calendar") if calendar == "" { calendar = "公历" } isTimeBetween := false //是否是时间区间 if chartType == 2 { dateType = 0 isTimeBetween = true } if dateType == 5 { isTimeBetween = true } fullEdb := new(response.EdbInfoFull) // 获取预测指标信息 edbInfo, err := data_manage.GetEdbInfoById(edbInfoId) if err != nil { br.Msg = "获取预测指标信息失败" br.ErrMsg = "获取预测指标信息失败,Err:" + err.Error() return } fullEdb.EdbInfo = edbInfo classifyList, err, errMsg := data.GetFullClassifyByClassifyId(edbInfo.ClassifyId) if err != nil { br.Msg = err.Error() br.ErrMsg = errMsg return } var currClassifyItem *data_manage.EdbClassifyIdItems for _, v := range classifyList { if v.ClassifyId == edbInfo.ClassifyId { currClassifyItem = v break } } if currClassifyItem != nil { fullEdb.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 } } var maxDate time.Time if edbInfo.LatestDate != "" { latestDateT, _ := time.Parse(utils.FormatDate, edbInfo.LatestDate) maxDate = latestDateT } if chartType == utils.CHART_TYPE_SEASON && dateType == utils.DateTypeNYears { // 季节性图需要特殊处理最近N年数据 maxDate = time.Date(maxDate.Year()+1, 1, 1, 0, 0, 0, 0, time.Local) } startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, maxDate) if endDate == "" { endDate = time.Now().Format(utils.FormatDate) } if dateType == 10 { startDate = "" endDate = "" } // 按钮校验 button := data.GetPredictEdbOpButton(this.SysUser, edbInfo.SysUserId, fullEdb.HaveOperaAuth) button.AddButton = false resp := response.PredictEdbInfoDataResp{ EdbInfo: fullEdb, Button: button, ClassifyList: classifyList, } if fullEdb.HaveOperaAuth { dataList, _, _, err, _ := data.GetPredictDataListByPredictEdbInfo(edbInfo, startDate, endDate, isTimeBetween) //lenDataList := len(dataList) //if lenDataList > 0 { // tmpValue := dataList[lenDataList-1] // // // 如果最大值 小于 预测值,那么将预测值作为最大值数据返回 // if edbInfo.MaxValue < tmpValue.Value { // edbInfo.MaxValue = tmpValue.Value // } // // // 如果最小值 大于 预测值,那么将预测值作为最小值数据返回 // if edbInfo.MinValue > tmpValue.Value { // edbInfo.MinValue = tmpValue.Value // } //} // 季节性图、公历、农历处理 resultDataList, err := data.GetChartDataList(dataList, chartType, calendar, edbInfo.LatestDate, startDate) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + err.Error() return } resp.DataList = resultDataList } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // ChartDataList // @Title 获取指标数据 // @Description 获取指标数据 // @Param request body data_manage.AddPredictEdbInfoReq true "type json string" // @Success 200 {object} data_manage.EdbInfoDataResp // @router /predict_edb_info/chart/data/list [post] func (this *PredictEdbInfoController) ChartDataList() { 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 request.PredictEdbInfoChartDataReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if req.SourceEdbInfoId <= 0 { br.Msg = "参数错误" return } dateType := req.DateType startDate := req.StartDate endDate := req.EndDate //seasonStartDate := req.SeasonStartDate //seasonEndDate := req.SeasonEndDate startYear := req.StartYear calendar := req.Calendar if calendar == "" { calendar = "公历" } isTimeBetween := false //是否是时间区间 if req.ChartType == 2 { dateType = 0 isTimeBetween = true } if dateType == 5 { isTimeBetween = true } // 规则列表 // 根据截止日期重新排序 ruleList := make([]request.RuleConfig, 0) { ruleMap := make(map[string]request.RuleConfig) ruleEndNumSortMap := make(map[int]request.RuleConfig) dateIntList := make([]int64, 0) endNumList := make([]int, 0) for _, v := range req.RuleList { if req.EndDateType == 0 { confEndDate, err := time.Parse(utils.FormatDate, v.EndDate) if err != nil { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error() br.IsSendEmail = false return } dateIntList = append(dateIntList, confEndDate.Unix()) ruleMap[v.EndDate] = v } else { if _, ok := ruleEndNumSortMap[v.EndNum]; ok { br.Msg = "所选期数不能和其他时间段相同" return } endNumList = append(endNumList, v.EndNum) ruleEndNumSortMap[v.EndNum] = v } } if req.EndDateType == 0 { sort.Slice(dateIntList, func(i, j int) bool { return dateIntList[i] < dateIntList[j] }) for _, dateInt := range dateIntList { currDateTime := time.Unix(dateInt, 0) item, ok := ruleMap[currDateTime.Format(utils.FormatDate)] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } else { sort.Ints(endNumList) for _, endNum := range endNumList { item, ok := ruleEndNumSortMap[endNum] if !ok { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择" br.IsSendEmail = false return } ruleList = append(ruleList, item) } } } // 预测指标配置 predictEdbConfAndDataList := make([]data_manage.PredictEdbConfAndData, 0) endDateStr := `` //数据的结束日期 for _, v := range ruleList { var confEndDate time.Time if v.EndDate != "" { endDateStr = v.EndDate //预测指标的结束日期 confEndDate, err = time.ParseInLocation(utils.FormatDate, v.EndDate, time.Local) if err != nil { br.Msg = "配置项中时间异常,请重新选择" br.ErrMsg = "配置项中时间异常,请重新选择,err:" + err.Error() return } } // 没有数据,自己瞎测试 //switch v.RuleType { //case 3: //3:同比 // v.Value = "0.1" //case 4: //4:同差 // v.Value = "10" //case 5: //5:环比 // v.Value = "0.1" //case 6: //6:环差 // v.Value = "0.1" //case 7: //7:N期移动均值 // v.Value = "5" //case 8: //8:N期段线性外推值 // v.Value = "5" //} tmpDataList := make([]*data_manage.EdbDataList, 0) switch v.RuleType { case 9: // 获取计算参数 /*formula, edbInfoList, edbInfoIdBytes, err, errMsg := data.GetCalculateByRuleByNineParams(v) if err != nil { br.Msg = "计算失败" if errMsg != "" { br.Msg = errMsg } br.Msg = err.Error() br.IsSendEmail = false return } // 获取计算数据 tmpDataList, err = data.CalculateByRuleByNine(formula, edbInfoList, edbInfoIdBytes, v.EmptyType, v.MaxEmptyType) if err != nil { br.Msg = "计算失败" br.ErrMsg = err.Error() br.IsSendEmail = false return }*/ reqJson, err := json.Marshal(v) respItem, err := data.PredictCalculateByNinePreview(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 } tmpDataList = respItem.Data.DataList } tmpPredictEdbConfAndData := data_manage.PredictEdbConfAndData{ ConfigId: 0, PredictEdbInfoId: 0, SourceEdbInfoId: req.SourceEdbInfoId, RuleType: v.RuleType, FixedValue: 0, Value: v.Value, EndDate: confEndDate, EndNum: v.EndNum, ModifyTime: time.Now(), CreateTime: time.Now(), DataList: tmpDataList, } predictEdbConfAndDataList = append(predictEdbConfAndDataList, tmpPredictEdbConfAndData) } // 来源指标 sourceEdbInfoItem, err := data_manage.GetEdbInfoById(req.SourceEdbInfoId) if err != nil { br.Msg = "获取来源指标信息失败" br.ErrMsg = "获取来源指标信息失败" if err.Error() != utils.ErrNoRow() { br.ErrMsg = "获取来源指标信息失败,Err:" + err.Error() } br.Success = true return } // todo 确认预测指标是否用的是来源指标的最新日期 var maxDate time.Time if sourceEdbInfoItem.LatestDate != "" { latestDateT, _ := time.Parse(utils.FormatDate, sourceEdbInfoItem.LatestDate) maxDate = latestDateT } startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, maxDate) if endDate == "" { endDate = time.Now().Format(utils.FormatDate) } if dateType == 10 { startDate = "" endDate = "" } minValue := sourceEdbInfoItem.MinValue maxValue := sourceEdbInfoItem.MaxValue allDataList := make([]*data_manage.EdbDataList, 0) //获取指标数据(实际已生成) dataList, err := data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, startDate, endDate) if err != nil { br.Msg = "获取失败" br.Msg = "获取失败,Err:" + err.Error() return } // 如果选择了日期,那么需要筛选所有的数据,用于未来指标的生成 if startDate != `` { allDataList, err = data_manage.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, "", "") if err != nil { br.Msg = "获取失败" br.Msg = "获取失败,Err:" + err.Error() return } } else { allDataList = dataList } // 获取预测指标未来的数据 if len(predictEdbConfAndDataList) > 0 { predictDataList := make([]*data_manage.EdbDataList, 0) if isTimeBetween { //如果是时间区间,那么 reqEndDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local) endDateTime, _ := time.ParseInLocation(utils.FormatDate, req.PredictEndDate, time.Local) // 如果选择的时间区间结束日期 晚于 当天,那么预测数据截止到当天 if reqEndDateTime.Before(endDateTime) { endDateStr = endDate } } // 获取预测数据 var predictMinValue, predictMaxValue float64 predictDataList, predictMinValue, predictMaxValue, err, errMsg := data.GetChartPredictEdbInfoDataListByConfList(predictEdbConfAndDataList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, req.EndDateType, sourceEdbInfoItem.Frequency, req.DataDateType, allDataList) if err != nil { br.Msg = "获取预测指标数据失败" if errMsg != `` { br.Msg = errMsg } br.ErrMsg = "获取预测指标数据失败:" + err.Error() return } dataList = append(dataList, predictDataList...) if len(predictDataList) > 0 { // 如果最小值 大于 预测值,那么将预测值作为最小值数据返回 if minValue > predictMinValue { minValue = predictMinValue } // 如果最大值 小于 预测值,那么将预测值作为最大值数据返回 if maxValue < predictMaxValue { maxValue = predictMaxValue } } } // 季节性图、公历、农历处理 resultDataList, err := data.GetChartDataList(dataList, req.ChartType, calendar, sourceEdbInfoItem.LatestDate, startDate) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + err.Error() return } resp := response.PredictEdbInfoChartDataResp{ MinValue: minValue, MaxValue: maxValue, DataList: resultDataList, } br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // PredictRuleCalculateByNine // @Title 根据预测规则9来计算数据 // @Description 获取指标数据 // @Param request body data_manage.RuleConfig true "type json string" // @Success 200 {object} data_manage.EdbInfoDataResp // @router /predict_edb_info/rule/calculate_by_nine [post] func (this *PredictEdbInfoController) PredictRuleCalculateByNine() { 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 request.RuleConfig err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } // 添加计算指标 reqJson, err := json.Marshal(req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } respItem, err := data.PredictCalculateByNinePreview(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 br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // Modify // @Title 修改指标信息接口 // @Description 编辑指标接口 // @Success 200 {object} request.EditEdbInfoReq // @router /predict_edb_info/modify [post] func (this *PredictEdbInfoController) Modify() { 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 request.ModifyPredictEdbInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } edbInfoId := req.EdbInfoId if edbInfoId <= 0 { br.Msg = "请选择预测指标" br.IsSendEmail = false return } edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoId) if err != nil { br.Msg = "修改失败" br.ErrMsg = "获取指标信息失败,Err:" + err.Error() return } var haveOperaAuth bool // 数据权限校验 { haveOperaAuth, err = data_manage_permission.CheckEdbPermissionByEdbInfoId(edbInfo.EdbInfoId, edbInfo.ClassifyId, edbInfo.IsJoinPermission, this.SysUser.AdminId) if err != nil { br.Msg = err.Error() br.ErrMsg = "校验指标权限失败,err:" + err.Error() return } } // 编辑权限校验 button := data.GetPredictEdbOpButton(this.SysUser, edbInfo.SysUserId, haveOperaAuth) if !button.OpButton { br.Msg = "无权限操作" br.IsSendEmail = false return } edbInfo.MaxValue = req.MaxValue edbInfo.MinValue = req.MinValue edbInfo.ModifyTime = time.Now() err = edbInfo.Update([]string{"MaxValue", "MinValue", "ModifyTime"}) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取失败,Err:" + err.Error() return } //修改es data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId) br.Ret = 200 br.Success = true br.Msg = "修改成功" br.IsAddLog = true } //func init() { // r := new(regression.Regression) // r.SetObserved("Murders per annum per 1,000,000 inhabitants") // r.SetVar(0, "Inhabitants") // r.SetVar(1, "Percent with incomes below $5000") // r.SetVar(2, "Percent unemployed") // r.Train( // regression.DataPoint(11.2, []float64{587000, 16.5, 6.2}), // regression.DataPoint(13.4, []float64{643000, 20.5, 6.4}), // regression.DataPoint(40.7, []float64{635000, 26.3, 9.3}), // regression.DataPoint(5.3, []float64{692000, 16.5, 5.3}), // regression.DataPoint(24.8, []float64{1248000, 19.2, 7.3}), // regression.DataPoint(12.7, []float64{643000, 16.5, 5.9}), // regression.DataPoint(20.9, []float64{1964000, 20.2, 6.4}), // regression.DataPoint(35.7, []float64{1531000, 21.3, 7.6}), // regression.DataPoint(8.7, []float64{713000, 17.2, 4.9}), // regression.DataPoint(9.6, []float64{749000, 14.3, 6.4}), // regression.DataPoint(14.5, []float64{7895000, 18.1, 6}), // regression.DataPoint(26.9, []float64{762000, 23.1, 7.4}), // regression.DataPoint(15.7, []float64{2793000, 19.1, 5.8}), // regression.DataPoint(36.2, []float64{741000, 24.7, 8.6}), // regression.DataPoint(18.1, []float64{625000, 18.6, 6.5}), // regression.DataPoint(28.9, []float64{854000, 24.9, 8.3}), // regression.DataPoint(14.9, []float64{716000, 17.9, 6.7}), // regression.DataPoint(25.8, []float64{921000, 22.4, 8.6}), // regression.DataPoint(21.7, []float64{595000, 20.2, 8.4}), // regression.DataPoint(25.7, []float64{3353000, 16.9, 6.7}), // ) // r.Run() // // fmt.Printf("Regression formula:\n%v\n", r.Formula) // //fmt.Printf("Regression:\n%s\n", r) //} //func init() { // //data := []float64{4080, 4070, 4070, 4020, 4020, 4010, 3950, 3980, 4000, 3990, 4020} // //median, _ := stats.Median(data) // //fmt.Println(median) // 3.65 // //stats.LinearRegression() // // //data := []float64{ , , , , , , , , } // // data := []Coordinate{ // {1, 4080}, // {2, 4070}, // {3, 4070}, // {4, 4020}, // {5, 4020}, // {6, 4010}, // {7, 3950}, // {8, 3980}, // {9, 4000}, // {10, 3990}, // {11, 4020}, // } // // //r, _ := ct(data) // // ct(data) // //fmt.Println(r) // //} //func init() { // data.AddOrEditAllEdbInfoToEs() //} // ClassifyEdbInfoItems // @Title 获取分类下指标接口 // @Description 获取分类下指标接口 // @Param ClassifyId query int true "分类id" // @Param IsShowMe query bool false "是否只看我的" // @Success 200 {object} data_manage.EdbClassifyListResp // @router /predict_edb_info/items [get] func (this *PredictEdbInfoController) ClassifyEdbInfoItems() { br := new(models.BaseResponse).Init() defer func() { this.Data["json"] = br this.ServeJSON() }() classifyId, _ := this.GetInt("ClassifyId") if classifyId <= 0 { br.Msg = "参数错误,请刷新页面" return } // 是否只看我的 isShowMe, _ := this.GetBool("IsShowMe") // 获取当前账号的不可见指标 obj := data_manage.EdbInfoNoPermissionAdmin{} confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error() return } noPermissionEdbInfoIdMap := make(map[int]bool) for _, v := range confList { noPermissionEdbInfoIdMap[v.EdbInfoId] = true } // 如果选择了只看我的,那么只查询归属于我的账号 sysUserId := 0 if isShowMe { sysUserId = this.SysUser.AdminId } allEdbInfo, err := data_manage.GetEdbInfoByClassifyId(classifyId, 1, sysUserId) if err != nil && err.Error() != utils.ErrNoRow() { br.Msg = "获取失败" br.ErrMsg = "获取数据失败,Err:" + err.Error() return } list := make([]*data_manage.EdbClassifyItems, 0) edbInfoNum := len(allEdbInfo) if edbInfoNum > 0 { classifyIdList := make([]int, 0) for _, v := range allEdbInfo { classifyIdList = append(classifyIdList, v.ClassifyId) } classifyList, err := data_manage.GetEdbClassifyByIdList(classifyIdList) if err != nil { br.Msg = "获取失败" br.ErrMsg = "获取分类数据失败,Err:" + err.Error() return } // 分类map classifyMap := make(map[int]*data_manage.EdbClassify) 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 _, v := range allEdbInfo { // 如果指标不可见,那么就不返回该指标 if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok { continue } // 数据权限 if classifyInfo, ok := classifyMap[v.ClassifyId]; ok { v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList) } button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth) button.AddButton = false //不管有没有权限,指标都是没有添加按钮的 v.Button = button list = append(list, v) } } resp := new(data_manage.ClassifyEdbInfoListResp) resp.EdbInfoList = list br.Ret = 200 br.Success = true br.Msg = "获取成功" br.Data = resp } // ChartImageSetBySvg // @Title 设置指标的图表图片 // @Description 设置指标的图表图片接口 // @Param request body data_manage.SetChartInfoImageReq true "type json string" // @Success Ret=200 保存成功 // @router /predict_edb_info/image/set_by_svg [post] func (this *PredictEdbInfoController) ChartImageSetBySvg() { 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 } imgData := this.GetString("Img") if imgData == "" { br.Msg = "图片参数错误" br.ErrMsg = "图片参数错误,Img Is Empty" return } edbInfoId, _ := this.GetInt("EdbInfoId", 0) if edbInfoId <= 0 { br.Msg = "指标参数错误" br.ErrMsg = "指标参数错误,EdbInfoId Is Empty" return } // 通过svg图片生成图片资源地址 resourceUrl, err, errMsg := services.GetResourceUrlBySvgImg(imgData) if err != nil { br.Msg = errMsg br.ErrMsg = err.Error() return } if edbInfoId <= 0 || resourceUrl == "" { br.Ret = 200 br.Success = true br.Msg = "保存成功" return } edbInfo, err := data_manage.GetEdbInfoById(edbInfoId) if err != nil { br.Msg = "保存失败" br.ErrMsg = "保存失败,Err:" + err.Error() if err.Error() == utils.ErrNoRow() { br.Msg = "找不到该指标" br.ErrMsg = "找不到该指标" br.IsSendEmail = false } return } edbInfo.ChartImage = resourceUrl err = edbInfo.Update([]string{"ChartImage"}) if err != nil { br.Msg = "保存失败" br.ErrMsg = "保存失败,Err:" + err.Error() return } //修改es数据 go data.AddOrEditEdbInfoToEs(edbInfoId) br.Ret = 200 br.Success = true br.Msg = "保存成功" } // AddStaticEdb // @Title 新增静态指标接口 // @Description 新增静态指标接口 // @Param request body request.AddPredictEdbInfoReq true "type json string" // @Success 200 {object} response.AddEdbInfoResp // @router /predict_edb_info/static_edb/add [post] func (this *PredictEdbInfoController) AddStaticEdb() { 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 } deleteCache := true cacheKey := "CACHE_EDB_INFO_ADD_" + strconv.Itoa(sysUser.AdminId) defer func() { if deleteCache { utils.Rc.Delete(cacheKey) } }() if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) { deleteCache = false br.Msg = "系统处理中,请稍后重试!" br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody) return } var req request.AddStaticPredictEdbInfoReq err := json.Unmarshal(this.Ctx.Input.RequestBody, &req) if err != nil { br.Msg = "参数解析异常!" br.ErrMsg = "参数解析失败,Err:" + err.Error() return } sourceEdbInfoId := req.SourceEdbInfoId if sourceEdbInfoId <= 0 { br.Msg = "请选择来源指标" br.IsSendEmail = false return } if req.EdbName == "" { br.Msg = "指标名称不能为空" br.IsSendEmail = false return } if req.ClassifyId <= 0 { br.Msg = "请选择分类" br.IsSendEmail = false return } if req.Frequency == "" { br.Msg = "请选择频度" br.IsSendEmail = false return } if req.Unit == "" { br.Msg = "请选择单位" br.IsSendEmail = false 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 } respItem, err := data.SavePredictStaticEdbData(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 } // EdbInfoBaseEdit // @Title 指标基础信息编辑接口 // @Description 指标基础信息编辑接口 // @Success 200 {object} data_manage.EditEdbInfoReq // @router /predict_edb_info/base/edit [post] func (this *PredictEdbInfoController) EdbInfoBaseEdit() { 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.EditEdbInfoReq 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.EdbInfoId <= 0 { br.Msg = "参数错误" br.ErrMsg = "指标id小于等于0" 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 } isSendEmail, err, errMsg := data.EditBaseEdbInfo(req, this.SysUser, this.Lang, string(this.Ctx.Input.RequestBody), this.Ctx.Input.URI()) if err != nil { br.Msg = errMsg br.ErrMsg = err.Error() br.IsSendEmail = isSendEmail return } br.Ret = 200 br.Success = true br.Msg = "保存成功" br.IsAddLog = true }