package excel import ( "encoding/json" "errors" "eta/eta_api/models/data_manage" "eta/eta_api/models/data_manage/excel/request" "eta/eta_api/services/data" "eta/eta_api/utils" "fmt" "strings" "time" ) // GetMixedTableCellData 获取混合表格数据 func GetMixedTableCellData(cellRelationConf string, config [][]request.MixedTableCellDataReq) (newMixedTableCellDataList [][]request.MixedTableCellDataReq, err error, errMsg string) { // 单元格关系配置x信息 cellRelationConfMap := make(map[string]request.CellRelationConf) cellRelationConfList := make([]request.CellRelationConf, 0) if cellRelationConf != `` { err = json.Unmarshal([]byte(cellRelationConf), &cellRelationConfList) if err != nil { return } for _, v := range cellRelationConfList { cellRelationConfMap[v.Key] = v } } // 找出所有的关联指标id config, edbInfoIdList, _, err, errMsg := handleConfig(config) if err != nil { return } // 查询所有关联的指标信息 edbInfoList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList) if err != nil { return } // 指标信息map edbInfoMap := make(map[int]*data_manage.EdbInfo) // 日度指标数据map edbDayDataListMap := make(map[int]map[string]float64) // 月度指标数据map edbMonthDataListMap := make(map[int]map[string]float64) // 日度指标数据map edbDataListMap := make(map[int][]*data_manage.EdbDataList) for _, edbInfo := range edbInfoList { edbInfoMap[edbInfo.EdbInfoId] = edbInfo dataList := make([]*data_manage.EdbDataList, 0) switch edbInfo.EdbInfoType { case 0: dataList, _ = data_manage.GetEdbDataList(edbInfo.Source, edbInfo.EdbInfoId, ``, ``) case 1: _, dataList, _, _, _, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false) default: err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType)) } dateValMap := make(map[string]float64) monthValMap := make(map[string]float64) for _, tmpData := range dataList { // 日度数据 dateValMap[tmpData.DataTime] = tmpData.Value // 月度数据(取该月份的第一个数据) yearMonth := strings.Join(strings.Split(tmpData.DataTime, "-")[0:2], "-") if _, ok := monthValMap[yearMonth]; !ok { monthValMap[yearMonth] = tmpData.Value } } edbDayDataListMap[edbInfo.EdbInfoId] = dateValMap edbMonthDataListMap[edbInfo.EdbInfoId] = monthValMap edbDataListMap[edbInfo.EdbInfoId] = dataList } // 单元格实际绑定的信息map cellDataRelationMap := make(map[string]request.MixedTableCellDataReq, 0) // 处理指定指标的日期 for k, row := range config { for i, cell := range row { // 单元格是日期类型,且是日导入指标日期(指标库的最新日期) if cell.DataType == request.DateDT && cell.DataTimeType == request.EdbDateDT { if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok { cell.ShowValue = edbInfo.EndDate cell.DataTime = edbInfo.EndDate config[k][i] = cell } } row[i] = cell cellDataRelationMap[cell.Uid] = cell } config[k] = row } type BaseCalculate struct { DataList []*data_manage.EdbDataList Frequency string `description:"需要转换的频度"` Formula interface{} Calendar string `description:"公历/农历"` MoveType int `description:"移动方式:1:领先(默认),2:滞后"` MoveFrequency string `description:"移动频度"` FromFrequency string `description:"来源的频度"` Source int `description:"1:累计值转月;2:累计值转季;3:同比值;4:同差值;5:N数值移动平均数计算;6:环比值;7:环差值;8:升频;9:降频;10:时间移位;11:超季节性;12:年化;13:累计值;14:累计值年初至今;15:指数修匀;16:日均值"` } // 指标计算的结果map edbSourceDataMap := make(map[string]map[string]float64) for k, row := range config { for i, cell := range row { switch cell.DataType { case request.EdbDT: // 指标类型 if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok { cell.ShowValue = edbInfo.EdbName } case request.InsertDataDT, request.PopInsertDataDT: // 数据类型 tmpDateList := strings.Split(cell.DataTime, "-") tmpDateValMap := make(map[string]float64) if len(tmpDateList) == 2 { //月度数据 if dateValMap, ok := edbMonthDataListMap[cell.EdbInfoId]; ok { tmpDateValMap = dateValMap } } else { // 日度数据 if dateValMap, ok := edbDayDataListMap[cell.EdbInfoId]; ok { tmpDateValMap = dateValMap } } if val, ok2 := tmpDateValMap[cell.DataTime]; ok2 { //cell.ShowValue = fmt.Sprint(val) cell.ShowValue = utils.FormatTableDataShowValue(val) } case request.InsertEdbCalculateDataDT: // 指标类型 // 日期 relationConf, ok := cellRelationConfMap[cell.Uid] if !ok { // 日期关系配置不存在 continue } if relationConf.RelationDate.Key == `` { // 日期关系配置未绑定 continue } relationCell, ok := cellDataRelationMap[relationConf.RelationDate.Key] if relationConf.RelationDate.Key == `` { // 找不到对应日期的单元格 continue } var tmpDataMap map[string]float64 key := utils.MD5(cell.Value) tmpDataMap, ok = edbSourceDataMap[key] if !ok { // 对应的配置值 var tmpConfig request.CalculateConf err = json.Unmarshal([]byte(cell.Value), &tmpConfig) if err != nil { return } tmpDataList, ok := edbDataListMap[tmpConfig.EdbInfoId] if !ok { continue } edbInfo, ok := edbInfoMap[tmpConfig.EdbInfoId] if !ok { continue } req2 := &BaseCalculate{ DataList: tmpDataList, Frequency: tmpConfig.Frequency, Formula: tmpConfig.Formula, Calendar: tmpConfig.Calendar, MoveType: tmpConfig.MoveType, MoveFrequency: tmpConfig.MoveFrequency, FromFrequency: edbInfo.Frequency, Source: tmpConfig.Source, } // 调用指标库去更新 reqJson, tmpErr := json.Marshal(req2) if tmpErr != nil { utils.FileLog.Error(fmt.Sprintf("计算失败1,配置信息;%s;错误原因:%s", cell.Value, tmpErr.Error())) err = tmpErr return } respItem, tmpErr := data.BaseCalculate(string(reqJson)) if tmpErr != nil { utils.FileLog.Error(fmt.Sprintf("计算失败2,配置信息;%s;错误原因:%s", cell.Value, tmpErr.Error())) err = tmpErr return } if respItem.Ret != 200 { utils.FileLog.Error(fmt.Sprintf("计算失败3,配置信息;%s;原因:%s;错误原因:%s", cell.Value, respItem.Msg, respItem.ErrMsg)) continue } tmpDataMap = respItem.Data.DataMap // 计算结果存一份,万一存在重复的计算方式,那么省的重新计算一下 edbSourceDataMap[key] = tmpDataMap } val := tmpDataMap[relationCell.DataTime] cell.ShowValue = utils.FormatTableDataShowValue(val) // } row[i] = cell } config[k] = row } newMixedTableCellDataList = config return } // handleConfig // @Description: 处理混合表格配置 // @author: Roc // @datetime2023-10-27 13:24:53 // @param configList [][]request.MixedTableCellDataReq // @return newConfig [][]request.MixedTableCellDataReq // @return edbInfoIdList []int // @return dataEdbInfoIdList []int // @return err error // @return errMsg string func handleConfig(configList [][]request.MixedTableCellDataReq) (newConfig [][]request.MixedTableCellDataReq, edbInfoIdList []int, dataEdbInfoIdList []int, err error, errMsg string) { edbInfoIdList = make([]int, 0) dataEdbInfoIdList = make([]int, 0) for ck, rowList := range configList { for rk, cell := range rowList { switch cell.DataType { case request.EdbDT: // 指标信息 edbInfoIdList = append(edbInfoIdList, cell.EdbInfoId) case request.InsertDataDT, request.PopInsertDataDT: // 插值、弹框插值 dataEdbInfoIdList = append(dataEdbInfoIdList, cell.EdbInfoId) case request.InsertEdbCalculateDataDT: // 插入指标计算公式生成的值 var config request.CalculateConf err = json.Unmarshal([]byte(cell.Value), &config) if err != nil { return } edbInfoIdList = append(edbInfoIdList, config.EdbInfoId) dataEdbInfoIdList = append(dataEdbInfoIdList, cell.EdbInfoId) case request.DateDT: // 日期类型 if cell.DataTimeType == request.EdbDateDT { var config request.EdbDateConf err = json.Unmarshal([]byte(cell.Value), &config) if err != nil { return } edbInfoIdList = append(edbInfoIdList, config.EdbInfoId) } else { date, tmpErr, tmpErrMsg := handleDate(cell.DataTimeType, cell.Value) if tmpErr != nil { err = tmpErr errMsg = tmpErrMsg return } rowList[rk].DataTime = date rowList[rk].ShowValue = date } } } configList[ck] = rowList } newConfig = configList return } // HandleDate // @Description: 日期处理 // @author: Roc // @datetime2023-10-27 09:37:02 // @param dataTimeType int // @param val string // @return date string // @return err error // @return errMsg string func HandleDate(dataTimeType int, val string) (date string, err error, errMsg string) { return handleDate(dataTimeType, val) } // handleDate // @Description: 日期处理 // @author: Roc // @datetime2023-10-27 09:36:49 // @param dataTimeType int // @param val string // @return date string // @return err error // @return errMsg string func handleDate(dataTimeType int, val string) (date string, err error, errMsg string) { if val == `` { errMsg = "错误的日期数据" err = errors.New(errMsg) return } switch dataTimeType { case request.CustomDateT: //手动输入日期 date = val case request.SystemDateT: // 系统日期 date, err, errMsg = handleSystemDateT(val) case request.EdbDateDT: // 导入指标日期(指标库的最新日期) default: errMsg = "错误的日期类型" err = errors.New(errMsg) return } return } // handleSystemDateT // @Description: 处理导入系统日期 // @author: Roc // @datetime2023-10-27 09:36:21 // @param confStr string // @return date string // @return err error // @return errMsg string func handleSystemDateT(confStr string) (date string, err error, errMsg string) { var config request.SystemDateConf err = json.Unmarshal([]byte(confStr), &config) if err != nil { return } switch config.Source { case request.SystemCurrDateT: date = time.Now().Format(utils.FormatDate) case request.SystemCalculateDateT: date, err, errMsg = handleSystemCalculateDateT(config.CalculateNum, config.CalculateFrequency) case request.SystemFrequencyDateT: // 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天) date, err, errMsg = handleSystemAppointDateT(config.Day, config.Frequency) default: errMsg = "错误的日期日期导入方式" err = errors.New(fmt.Sprint("错误的日期日期导入方式:", config.Source)) return } return } // handleSystemCalculateDateT // @Description: 处理系统日期计算后的日期 // @author: Roc // @datetime2023-10-27 09:31:22 // @param num int // @param frequency string // @return date string // @return err error // @return errMsg string func handleSystemCalculateDateT(num int, frequency string) (date string, err error, errMsg string) { if err != nil { return } currDate := time.Now() switch frequency { case "", "日": date = currDate.AddDate(0, 0, num).Format(utils.FormatDate) default: errMsg = "错误的日期频度:" + frequency err = errors.New(errMsg) return } return } // handleSystemAppointDateT // @Description: 处理系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天) // @author: Roc // @datetime2023-10-27 09:31:35 // @param Frequency string // @param Day string // @return date string // @return err error // @return errMsg string func handleSystemAppointDateT(appointDay, frequency string) (date string, err error, errMsg string) { currDate := time.Now() switch frequency { case "本周": day := int(currDate.Weekday()) if day == 0 { // 周日 day = 7 } num := 0 switch appointDay { case "周一": num = 1 case "周二": num = 2 case "周三": num = 3 case "周四": num = 4 case "周五": num = 5 case "周六": num = 6 case "周日": num = 7 } day = num - day date = currDate.AddDate(0, 0, day).Format(utils.FormatDate) case "本旬": day := currDate.Day() var tmpDate time.Time switch appointDay { case "第一天": if day <= 10 { tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location()) } else if day <= 20 { tmpDate = time.Date(currDate.Year(), currDate.Month(), 11, 0, 0, 0, 0, currDate.Location()) } else { tmpDate = time.Date(currDate.Year(), currDate.Month(), 21, 0, 0, 0, 0, currDate.Location()) } case "最后一天": if day <= 10 { tmpDate = time.Date(currDate.Year(), currDate.Month(), 10, 0, 0, 0, 0, currDate.Location()) } else if day <= 20 { tmpDate = time.Date(currDate.Year(), currDate.Month(), 20, 0, 0, 0, 0, currDate.Location()) } else { tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1) } } date = tmpDate.Format(utils.FormatDate) case "本月": var tmpDate time.Time switch appointDay { case "第一天": tmpDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, currDate.Location()) case "最后一天": tmpDate = time.Date(currDate.Year(), currDate.Month()+1, 1, 0, 0, 0, 0, currDate.Location()).AddDate(0, 0, -1) } date = tmpDate.Format(utils.FormatDate) case "本季": month := currDate.Month() var tmpDate time.Time switch appointDay { case "第一天": if month <= 3 { tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location()) } else if month <= 6 { tmpDate = time.Date(currDate.Year(), 4, 1, 0, 0, 0, 0, currDate.Location()) } else if month <= 9 { tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location()) } else { tmpDate = time.Date(currDate.Year(), 10, 1, 0, 0, 0, 0, currDate.Location()) } case "最后一天": if month <= 3 { tmpDate = time.Date(currDate.Year(), 3, 31, 0, 0, 0, 0, currDate.Location()) } else if month <= 6 { tmpDate = time.Date(currDate.Year(), 6, 30, 0, 0, 0, 0, currDate.Location()) } else if month <= 9 { tmpDate = time.Date(currDate.Year(), 9, 30, 0, 0, 0, 0, currDate.Location()) } else { tmpDate = time.Date(currDate.Year(), 12, 31, 0, 0, 0, 0, currDate.Location()) } } date = tmpDate.Format(utils.FormatDate) default: errMsg = "错误的日期频度:" + frequency err = errors.New(errMsg) return } return }