|
@@ -151,11 +151,17 @@ func GetMixedTableCellData(mixedTableReq request.MixedTableReq) (newMixedTableCe
|
|
// 基础计算单元格的位置信息
|
|
// 基础计算单元格的位置信息
|
|
calculateCellMap := make(map[string]Cell)
|
|
calculateCellMap := make(map[string]Cell)
|
|
calculateChainList := make([]string, 0)
|
|
calculateChainList := make([]string, 0)
|
|
-
|
|
|
|
|
|
+ dateCalculateList := make([]string, 0)
|
|
// 处理单元格中的数据类型(除去基础计算,因为这个是依赖于其他)
|
|
// 处理单元格中的数据类型(除去基础计算,因为这个是依赖于其他)
|
|
for k, row := range config {
|
|
for k, row := range config {
|
|
for i, cell := range row {
|
|
for i, cell := range row {
|
|
switch cell.DataType {
|
|
switch cell.DataType {
|
|
|
|
+ case request.DateDT: // 日期类型
|
|
|
|
+ calculateCellMap[cell.Uid] = Cell{
|
|
|
|
+ Column: k,
|
|
|
|
+ Row: i,
|
|
|
|
+ CellInfo: cell,
|
|
|
|
+ }
|
|
case request.EdbDT: // 指标类型
|
|
case request.EdbDT: // 指标类型
|
|
if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok {
|
|
if edbInfo, ok := edbInfoMap[cell.EdbInfoId]; ok {
|
|
cell.ShowValue = edbInfo.EdbName
|
|
cell.ShowValue = edbInfo.EdbName
|
|
@@ -380,6 +386,15 @@ func GetMixedTableCellData(mixedTableReq request.MixedTableReq) (newMixedTableCe
|
|
val := tmpDataMap[cellDateTime]
|
|
val := tmpDataMap[cellDateTime]
|
|
cellKeyVal[cell.Uid] = val
|
|
cellKeyVal[cell.Uid] = val
|
|
cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
|
|
+ case request.DateCalculateDataDT: //日期计算
|
|
|
|
+ // 把关联的单元格存在数组里
|
|
|
|
+ calculateCellMap[cell.Uid] = Cell{
|
|
|
|
+ Column: k,
|
|
|
|
+ Row: i,
|
|
|
|
+ CellInfo: cell,
|
|
|
|
+ }
|
|
|
|
+ dateCalculateList = append(dateCalculateList, cell.Uid)
|
|
|
|
+ // 遍历数组,根据公式进行计算,并将得到的结果放到对应的单元格中
|
|
}
|
|
}
|
|
|
|
|
|
row[i] = cell
|
|
row[i] = cell
|
|
@@ -419,6 +434,11 @@ func GetMixedTableCellData(mixedTableReq request.MixedTableReq) (newMixedTableCe
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 日期计算
|
|
|
|
+ config, err, errMsg = handlerDateCalculate(dateCalculateList, calculateCellMap, config)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
newMixedTableCellDataList = config
|
|
newMixedTableCellDataList = config
|
|
|
|
|
|
return
|
|
return
|
|
@@ -1008,3 +1028,129 @@ func calculateByCellList(calculateFormula string, tagList []utils.CellPosition)
|
|
|
|
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// handlerDateCalculate 处理日期计算
|
|
|
|
+func handlerDateCalculate(dateCalculateList []string, calculateCellMap map[string]Cell, oldConfig [][]request.MixedTableCellDataReq) (config [][]request.MixedTableCellDataReq, err error, errMsg string) {
|
|
|
|
+ config = oldConfig
|
|
|
|
+ if len(dateCalculateList) == 0 {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if len(dateCalculateList) > 0 {
|
|
|
|
+ for _, cellKey := range dateCalculateList {
|
|
|
|
+ // 查找这个单元格的位置,直接map找了,而不是遍历整个单元格
|
|
|
|
+ cellPosition, ok := calculateCellMap[cellKey]
|
|
|
|
+ if !ok {
|
|
|
|
+ utils.FileLog.Error("找不到单元格位置:", cellKey)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cell := config[cellPosition.Column][cellPosition.Row]
|
|
|
|
+ if cell.DataType != request.DateCalculateDataDT { // 判断公式计算(A+B这种)类型,不是的话也过滤了
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ val, tmpErr, tmpErrMsg := dateCalculate(calculateCellMap, cell.Value)
|
|
|
|
+ if tmpErr != nil {
|
|
|
|
+ errMsg = tmpErrMsg
|
|
|
|
+ err = tmpErr
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cell.ShowValue = utils.FormatTableDataShowValue(val)
|
|
|
|
+ config[cellPosition.Column][cellPosition.Row] = cell
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func dateCalculate(calculateCellMap map[string]Cell, config string) (val float64, err error, errMsg string) {
|
|
|
|
+ var edbDateConf request.MixDateCalculateConf
|
|
|
|
+ err = json.Unmarshal([]byte(config), &edbDateConf)
|
|
|
|
+ if err != nil {
|
|
|
|
+ err = fmt.Errorf("日期计算配置json解析失败失败: %s, Err:%s", config, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if len(edbDateConf.RelationCellList) == 0 {
|
|
|
|
+ err = fmt.Errorf("日期计算 未配置日期单元格失败: %s", config)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ valMap := make(map[string]int)
|
|
|
|
+ for _, v := range edbDateConf.RelationCellList {
|
|
|
|
+ // 查找单元格数据
|
|
|
|
+ cell, ok := calculateCellMap[v.Uid]
|
|
|
|
+ if !ok {
|
|
|
|
+ err = fmt.Errorf("查找单元格:%s 的数据失败", v.Uid)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ colData := cell.CellInfo
|
|
|
|
+
|
|
|
|
+ // 如果不是基础计算单元格,直接返回
|
|
|
|
+ _, err = time.ParseInLocation(utils.FormatDate, colData.ShowValue, time.Local)
|
|
|
|
+ if err != nil {
|
|
|
|
+ err = fmt.Errorf("%s 的单元格非日期类型, Err: %s", colData.ShowValue, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // todo 把日期转换成excel里的天数
|
|
|
|
+ realDiffDay := utils.GetDaysDiff1900(colData.ShowValue)
|
|
|
|
+
|
|
|
|
+ valMap[strings.ToUpper(v.Tag)] = realDiffDay
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算
|
|
|
|
+ val, errMsg, err = dateFormulaCalculate(valMap, edbDateConf.Formula)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func dateFormulaCalculate(valTagMap map[string]int, calculateFormula string) (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)
|
|
|
|
+
|
|
|
|
+ formulaFormStr := utils.ReplaceFormulaByTagMap(valTagMap, calculateFormula)
|
|
|
|
+
|
|
|
|
+ if formulaFormStr == `` {
|
|
|
|
+ errMsg = "公式异常"
|
|
|
|
+ err = errors.New(errMsg)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ fmt.Println("公式:" + formulaFormStr)
|
|
|
|
+ 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
|
|
|
|
+}
|