|
@@ -0,0 +1,769 @@
|
|
|
|
+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"
|
|
|
|
+ "github.com/shopspring/decimal"
|
|
|
|
+ "github.com/yidane/formula"
|
|
|
|
+ "sort"
|
|
|
|
+ "strconv"
|
|
|
|
+ "strings"
|
|
|
|
+ "time"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// BaseCalculate
|
|
|
|
+// @Description: 指标数据计算请求
|
|
|
|
+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:日均值"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Cell
|
|
|
|
+// @Description: 单元格位置
|
|
|
|
+type Cell struct {
|
|
|
|
+ Column int `description:"行"`
|
|
|
|
+ Row int `description:"列"`
|
|
|
|
+ CellInfo request.MixedTableCellDataReq `description:"对应的单元格信息"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// GetMixedTableCellData 获取混合表格数据
|
|
|
|
+func GetMixedTableCellData(mixedTableReq request.MixedTableReq) (newMixedTableCellDataList [][]request.MixedTableCellDataReq, err error, errMsg string) {
|
|
|
|
+ cellRelationConf := mixedTableReq.CellRelation
|
|
|
|
+ config := mixedTableReq.Data
|
|
|
|
+
|
|
|
|
+ // 单元格关系配置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
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 指标计算的结果map
|
|
|
|
+ edbSourceDataMap := make(map[string]map[string]float64)
|
|
|
|
+
|
|
|
|
+ // 单元格对应的key与他的值(只处理数据类型)
|
|
|
|
+ cellKeyVal := make(map[string]float64)
|
|
|
|
+
|
|
|
|
+ // 基础计算单元格的位置信息
|
|
|
|
+ calculateCellMap := make(map[string]Cell)
|
|
|
|
+ calculateChainList := make([]string, 0)
|
|
|
|
+
|
|
|
|
+ // 处理单元格中的数据类型(除去基础计算,因为这个是依赖于其他)
|
|
|
|
+ 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: // 数据类型
|
|
|
|
+ if cell.DataTime == `` {
|
|
|
|
+ // 指标的最新日期
|
|
|
|
+ if dateValList, ok := edbDataListMap[cell.EdbInfoId]; ok {
|
|
|
|
+ tmpLenData := len(dateValList)
|
|
|
|
+ if tmpLenData > 0 {
|
|
|
|
+ cellKeyVal[cell.Uid] = dateValList[tmpLenData-1].Value
|
|
|
|
+ cell.ShowValue = utils.FormatTableDataShowValue(dateValList[tmpLenData-1].Value)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ 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)
|
|
|
|
+ cellKeyVal[cell.Uid] = val
|
|
|
|
+ cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ calculateCellMap[cell.Uid] = Cell{
|
|
|
|
+ Column: k,
|
|
|
|
+ Row: i,
|
|
|
|
+ CellInfo: cell,
|
|
|
|
+ }
|
|
|
|
+ case request.CustomTextDT: //自定义文本
|
|
|
|
+ if cell.Value == `` {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // 处理看下能否转成float,如果可以的话,说明这个也是可以参与计算的
|
|
|
|
+ tmpDeci, tmpErr := decimal.NewFromString(cell.Value)
|
|
|
|
+ if tmpErr == nil {
|
|
|
|
+ tmpVal, _ := tmpDeci.Float64()
|
|
|
|
+ cellKeyVal[cell.Uid] = tmpVal
|
|
|
|
+
|
|
|
|
+ calculateCellMap[cell.Uid] = Cell{
|
|
|
|
+ Column: k,
|
|
|
|
+ Row: i,
|
|
|
|
+ CellInfo: cell,
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ case request.FormulateCalculateDataDT: // 公式计算(A+B这种)
|
|
|
|
+ calculateCellMap[cell.Uid] = Cell{
|
|
|
|
+ Column: k,
|
|
|
|
+ Row: i,
|
|
|
|
+ CellInfo: cell,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ calculateChainList = append(calculateChainList, cell.Uid)
|
|
|
|
+
|
|
|
|
+ case request.InsertEdbCalculateDataDT: // 插入指标系统计算公式生成的值
|
|
|
|
+ // 日期
|
|
|
|
+ var cellDateTime string
|
|
|
|
+ // 日期关系配置不存在,则默认最新数据
|
|
|
|
+ if relationConf, ok := cellRelationConfMap[cell.Uid]; ok {
|
|
|
|
+ if relationConf.RelationDate.Key == `` {
|
|
|
|
+ // 日期关系配置未绑定
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ // 配置
|
|
|
|
+ relationCell, ok := cellDataRelationMap[relationConf.RelationDate.Key]
|
|
|
|
+ if !ok {
|
|
|
|
+ // 找不到对应日期的单元格
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+ cellDateTime = relationCell.DataTime
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ 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
|
|
|
|
+
|
|
|
|
+ lenDataList := len(respItem.Data.DateList)
|
|
|
|
+ if cellDateTime == `` && lenDataList > 0 {
|
|
|
|
+ cellDateTime = respItem.Data.DateList[lenDataList-1]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ val := tmpDataMap[cellDateTime]
|
|
|
|
+ cellKeyVal[cell.Uid] = val
|
|
|
|
+ cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ row[i] = cell
|
|
|
|
+ }
|
|
|
|
+ config[k] = row
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 公式链计算
|
|
|
|
+ if len(calculateChainList) > 0 {
|
|
|
|
+ for _, cellKey := range calculateChainList {
|
|
|
|
+ // 查找这个单元格的位置,直接map找了,而不是遍历整个单元格
|
|
|
|
+ cellPosition, ok := calculateCellMap[cellKey]
|
|
|
|
+ if !ok {
|
|
|
|
+ utils.FileLog.Error("找不到单元格位置:", cellKey)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cell := config[cellPosition.Column][cellPosition.Row]
|
|
|
|
+ if cell.DataType != request.FormulateCalculateDataDT { // 判断公式计算(A+B这种)类型,不是的话也过滤了
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ val, has, tmpErr, tmpErrMsg := getCalculateValueByCell(calculateCellMap, cellKey, cellKeyVal)
|
|
|
|
+ if tmpErr != nil {
|
|
|
|
+ errMsg = tmpErrMsg
|
|
|
|
+ err = tmpErr
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if !has {
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cellKeyVal[cell.Uid] = val
|
|
|
|
+ cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
|
|
+ config[cellPosition.Column][cellPosition.Row] = cell
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ newMixedTableCellDataList = config
|
|
|
|
+
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// getCalculateValue 获取公式计算的结果
|
|
|
|
+func getCalculateValueByCell(calculateCellMap map[string]Cell, key string, cellKeyValMap map[string]float64) (val float64, has bool, err error, errMsg string) {
|
|
|
|
+ // 单元格的标签名
|
|
|
|
+ val, ok := cellKeyValMap[key]
|
|
|
|
+ if ok {
|
|
|
|
+ has = true
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查找单元格数据
|
|
|
|
+ cell, ok := calculateCellMap[key]
|
|
|
|
+ if !ok {
|
|
|
|
+ err = errors.New("查找单元格" + key + "的数据失败")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ colData := cell.CellInfo
|
|
|
|
+
|
|
|
|
+ // 如果不是基础计算单元格,直接返回
|
|
|
|
+ if colData.DataType != request.FormulateCalculateDataDT {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果是计算单元格
|
|
|
|
+
|
|
|
|
+ tagList := make([]utils.CellPosition, 0)
|
|
|
|
+ // 计算单元格relationCellList
|
|
|
|
+ var relationCellList []request.RelationCell
|
|
|
|
+ if colData.Extra == `` {
|
|
|
|
+ err = errors.New(colData.Uid + "没有绑定关系")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ err = json.Unmarshal([]byte(colData.Extra), &relationCellList)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for _, relation := range relationCellList {
|
|
|
|
+ //relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
|
|
|
|
+ tmpVal, _, tmpErr, tmpErrMsg := getCalculateValueByCell(calculateCellMap, relation.Key, cellKeyValMap)
|
|
|
|
+ if tmpErr != nil {
|
|
|
|
+ errMsg = tmpErrMsg
|
|
|
|
+ err = tmpErr
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ cellKeyValMap[relation.Key] = tmpVal
|
|
|
|
+
|
|
|
|
+ rowInt, tmpErr := strconv.Atoi(relation.Row)
|
|
|
|
+ if tmpErr != nil {
|
|
|
|
+ err = tmpErr
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ tagList = append(tagList, utils.CellPosition{
|
|
|
|
+ Tag: relation.Tag,
|
|
|
|
+ Row: rowInt,
|
|
|
|
+ Value: tmpVal,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算
|
|
|
|
+ val, errMsg, err = calculateByCellList(strings.ToUpper(colData.Value), tagList)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 重新赋值
|
|
|
|
+ has = true
|
|
|
|
+ cellKeyValMap[key] = val
|
|
|
|
+
|
|
|
|
+ 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)
|
|
|
|
+ case "本半年":
|
|
|
|
+ month := currDate.Month()
|
|
|
|
+ var tmpDate time.Time
|
|
|
|
+ switch appointDay {
|
|
|
|
+ case "第一天":
|
|
|
|
+ if month <= 6 {
|
|
|
|
+ tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
|
|
|
|
+ } else {
|
|
|
|
+ tmpDate = time.Date(currDate.Year(), 7, 1, 0, 0, 0, 0, currDate.Location())
|
|
|
|
+ }
|
|
|
|
+ case "最后一天":
|
|
|
|
+ if month <= 6 {
|
|
|
|
+ tmpDate = time.Date(currDate.Year(), 6, 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)
|
|
|
|
+ case "本年":
|
|
|
|
+ var tmpDate time.Time
|
|
|
|
+ switch appointDay {
|
|
|
|
+ case "第一天":
|
|
|
|
+ tmpDate = time.Date(currDate.Year(), 1, 1, 0, 0, 0, 0, currDate.Location())
|
|
|
|
+ case "最后一天":
|
|
|
|
+ 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
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// calculateByCellList
|
|
|
|
+// @Description: 根据单元格来进行公式计算
|
|
|
|
+// @author: Roc
|
|
|
|
+// @datetime2023-11-14 16:17:38
|
|
|
|
+// @param calculateFormula string
|
|
|
|
+// @param tagList []utils.CellPosition
|
|
|
|
+// @return calVal string
|
|
|
|
+// @return errMsg string
|
|
|
|
+// @return err error
|
|
|
|
+func calculateByCellList(calculateFormula string, tagList []utils.CellPosition) (calVal float64, errMsg string, err error) {
|
|
|
|
+ if calculateFormula == "" {
|
|
|
|
+ errMsg = "公式异常"
|
|
|
|
+ err = errors.New(errMsg)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ calculateFormula = strings.TrimPrefix(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)
|
|
|
|
+
|
|
|
|
+ rowList := make([]int, 0)
|
|
|
|
+ rowListMap := make(map[int][]utils.CellPosition)
|
|
|
|
+ for _, v := range tagList {
|
|
|
|
+ tmpRowList, ok := rowListMap[v.Row]
|
|
|
|
+ if !ok {
|
|
|
|
+ rowList = append(rowList, v.Row)
|
|
|
|
+ tmpRowList = make([]utils.CellPosition, 0)
|
|
|
|
+ }
|
|
|
|
+ tmpRowList = append(tmpRowList, v)
|
|
|
|
+ rowListMap[v.Row] = tmpRowList
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sort.Ints(rowList)
|
|
|
|
+
|
|
|
|
+ list := make([]utils.CellPosition, 0)
|
|
|
|
+ for _, row := range rowList {
|
|
|
|
+ list = append(list, rowListMap[row]...)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ formulaFormStr := utils.ReplaceFormulaByCellList(list, calculateFormula)
|
|
|
|
+ //计算公式异常,那么就移除该指标
|
|
|
|
+ if formulaFormStr == `` {
|
|
|
|
+ errMsg = "公式异常"
|
|
|
|
+ err = errors.New(errMsg)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ expression := formula.NewExpression(formulaFormStr)
|
|
|
|
+ calResult, err := expression.Evaluate()
|
|
|
|
+ if err != nil {
|
|
|
|
+ errMsg = "计算失败"
|
|
|
|
+ err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
|
|
|
|
+ // 分母为0的报错
|
|
|
|
+ if strings.Contains(err.Error(), "divide by zero") {
|
|
|
|
+ errMsg = "分母不能为0"
|
|
|
|
+ err = errors.New("分母不能为空,计算公式:" + formulaFormStr)
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 如果计算结果是NAN,那么就提示报错
|
|
|
|
+ if calResult.IsNan() {
|
|
|
|
+ errMsg = "计算失败"
|
|
|
|
+ err = errors.New("计算失败:计算结果是:NAN;formulaStr:" + formulaFormStr)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ calVal, err = calResult.Float64()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 转Decimal然后四舍五入
|
|
|
|
+ calVal, _ = decimal.NewFromFloat(calVal).Round(4).Float64()
|
|
|
|
+
|
|
|
|
+ return
|
|
|
|
+}
|