浏览代码

新增计算指标刷新

hongze 3 年之前
父节点
当前提交
441ec83b57

+ 6 - 2
go.sum

@@ -8,11 +8,12 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
 github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
-github.com/aliyun/aliyun-oss-go-sdk v1.9.8 h1:BOflvK0Zs/zGmoabyFIzTg5c3kguktWTXEwewwbuba0=
 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible h1:hLUNPbx10wawWW7DeNExvTrlb90db3UnnNTFKHZEFhE=
 github.com/aliyun/aliyun-oss-go-sdk v2.1.8+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
 github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
 github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
+github.com/antlr/antlr4 v0.0.0-20190325153624-837aa60e2c47 h1:Lp5nUoQzppfVmfZadpzAytNyb5IMtxyOJLzoQS5dExg=
+github.com/antlr/antlr4 v0.0.0-20190325153624-837aa60e2c47/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
 github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ=
 github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
 github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
@@ -35,7 +36,6 @@ github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGii
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dgrijalva/jwt-go v1.0.2 h1:KPldsxuKGsS2FPWsNeg9ZO18aCrGKujPoWXn2yo+KQM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
@@ -85,7 +85,9 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
+github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -144,6 +146,8 @@ github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
 github.com/tealeg/xlsx v1.0.5/go.mod h1:btRS8dz54TDnvKNosuAqxrM1QgN1udgk9O34bDCnORM=
 github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
 github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
+github.com/yidane/formula v0.0.0-20200220154705-ec0e6bc4831b h1:e9CwJGPvgp5/7wHQcQg0ImESNHOTQfyrrPj6QYloA6A=
+github.com/yidane/formula v0.0.0-20200220154705-ec0e6bc4831b/go.mod h1:vUhtXwXDSh8NKHxIGRY1HvLhoC4Hba1RL62whvmtPUk=
 github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

+ 58 - 0
models/data_manage/edb_data_calculate.go

@@ -0,0 +1,58 @@
+package data_manage
+
+import (
+	"rdluck_tools/orm"
+	"time"
+)
+
+func GetEdbDataCalculateByCodeAndDate(edbCode string, startDate string) (count int, err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	sql := ` SELECT COUNT(1) AS count FROM edb_data_calculate WHERE edb_code=? AND data_time=? `
+	err = o.Raw(sql, edbCode, startDate).QueryRow(&count)
+	return
+}
+
+func ModifyEdbDataCalculate(edbInfoId int64, dataTime string, value float64) (err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	sql := ` UPDATE edb_data_calculate SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+	_, err = o.Raw(sql, value, edbInfoId, dataTime).Exec()
+	return
+}
+
+
+func AddEdbDataCalculateBySql(sqlStr string) (err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	_, err = o.Raw(sqlStr).Exec()
+	return
+}
+
+
+type EdbInfoCalculateDetail struct {
+	EdbInfoCalculateId int       `orm:"column(edb_info_calculate_id);pk"`
+	EdbInfoId          int       `description:"指标id"`
+	EdbCode            string    `description:"指标编码"`
+	FromEdbInfoId      int       `description:"计算指标id"`
+	FromEdbCode        string    `description:"计算指标编码"`
+	FromEdbName        string    `description:"计算指标名称"`
+	FromSource         int       `description:"计算指标来源"`
+	FromSourceName     string    `description:"计算指标来源名称"`
+	FromTag            string    `description:"来源指标标签"`
+	Sort               int       `description:"计算指标名称排序"`
+	CreateTime         time.Time `description:"创建时间"`
+	ModifyTime         time.Time `description:"修改时间"`
+	StartDate          string    `description:"开始日期"`
+	EndDate            string    `description:"结束日期"`
+}
+
+func GetEdbInfoCalculateDetail(edbInfoId int) (list []*EdbInfoCalculateDetail, err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	sql := ` SELECT a.*,b.start_date,b.end_date FROM edb_info_calculate AS a
+			INNER JOIN edb_info AS b ON a.from_edb_info_id=b.edb_info_id
+			WHERE a.edb_info_id=? ORDER BY sort ASC `
+	_, err = o.Raw(sql, edbInfoId).QueryRows(&list)
+	return
+}

+ 82 - 13
models/data_manage/edb_info.go

@@ -9,18 +9,46 @@ import (
 	"time"
 )
 
+type EdbInfo struct {
+	EdbInfoId        int    `orm:"column(edb_info_id);pk"`
+	SourceName       string `description:"来源名称"`
+	Source           int    `description:"来源id"`
+	EdbCode          string `description:"指标编码"`
+	EdbName          string `description:"指标名称"`
+	EdbNameSource    string `description:"指标名称来源"`
+	Frequency        string `description:"频率"`
+	Unit             string `description:"单位"`
+	StartDate        string `description:"起始日期"`
+	EndDate          string `description:"终止日期"`
+	ClassifyId       int    `description:"分类id"`
+	SysUserId        int
+	SysUserRealName  string
+	UniqueCode       string `description:"指标唯一编码"`
+	CreateTime       time.Time
+	ModifyTime       time.Time
+	MinValue         float64 `description:"指标最小值"`
+	MaxValue         float64 `description:"指标最大值"`
+	CalculateFormula string  `description:"计算公式"`
+}
+
 type EdbInfoList struct {
-	EdbInfoId  int       `orm:"column(edb_info_id);pk"`
-	SourceName string    `description:"来源名称"`
-	Source     int       `description:"来源id"`
-	EdbCode    string    `description:"指标编码"`
-	EdbName    string    `description:"指标名称"`
-	Frequency  string    `description:"频率"`
-	Unit       string    `description:"单位"`
-	StartDate  time.Time `description:"起始日期"`
-	EndDate    time.Time `description:"终止日期"`
-	ClassifyId int       `description:"分类id"`
-	UniqueCode string    `description:"指标唯一编码"`
+	EdbInfoId        int       `orm:"column(edb_info_id);pk"`
+	SourceName       string    `description:"来源名称"`
+	Source           int       `description:"来源id"`
+	EdbCode          string    `description:"指标编码"`
+	EdbName          string    `description:"指标名称"`
+	Frequency        string    `description:"频率"`
+	Unit             string    `description:"单位"`
+	StartDate        time.Time `description:"起始日期"`
+	EndDate          time.Time `description:"终止日期"`
+	ClassifyId       int       `description:"分类id"`
+	UniqueCode       string    `description:"指标唯一编码"`
+	CalculateFormula string    `description:"计算公式"`
+}
+
+type EdbInfoSearchData struct {
+	DataTime string  `description:"数据日期"`
+	Value    float64 `description:"数据"`
 }
 
 func GetEdbInfoByCondition(condition string, pars []interface{}) (item []*EdbInfoList, err error) {
@@ -30,7 +58,7 @@ func GetEdbInfoByCondition(condition string, pars []interface{}) (item []*EdbInf
 	if condition != "" {
 		sql += condition
 	}
-	_,err = o.Raw(sql, pars).QueryRows(&item)
+	_, err = o.Raw(sql, pars).QueryRows(&item)
 	return
 }
 
@@ -71,11 +99,52 @@ func GetEdbInfoMaxAndMinInfo(source int, edbCode string) (item *EdbInfoMaxAndMin
 	return
 }
 
-
 func ModifyEdbInfoMaxAndMinInfo(edbInfoId int, item *EdbInfoMaxAndMinInfo) (err error) {
 	o := orm.NewOrm()
 	o.Using("data")
 	sql := ` UPDATE edb_info SET start_date=?,end_date=?,min_value=?,max_value=?,modify_time=NOW() WHERE edb_info_id=? `
 	_, err = o.Raw(sql, item.MinDate, item.MaxDate, item.MinValue, item.MaxValue, edbInfoId).Exec()
 	return
+}
+
+func GetEdbDataListAll(condition string, pars []interface{}, source int) (item []*EdbInfoSearchData, err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	sql := ``
+	tableName := GetEdbDataTableName(source)
+	sql = ` SELECT * FROM %s WHERE 1=1 `
+	sql = fmt.Sprintf(sql, tableName)
+
+	if condition != "" {
+		sql += condition
+	}
+
+	sql += ` ORDER BY data_time ASC `
+	_, err = o.Raw(sql, pars).QueryRows(&item)
+	return
+}
+
+func GetEdbDataTableName(source int) (tableName string) {
+	if source == utils.DATA_SOURCE_THS {
+		tableName = `edb_data_ths`
+	} else if source == utils.DATA_SOURCE_WIND {
+		tableName = `edb_data_wind`
+	} else if source == utils.DATA_SOURCE_PB {
+		tableName = `edb_data_pb`
+	} else if source == utils.DATA_SOURCE_CALCULATE {
+		tableName = `edb_data_calculate`
+	} else {
+		tableName = ""
+		errors.New("无效的渠道:" + strconv.Itoa(source))
+		return
+	}
+	return
+}
+
+func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) {
+	o := orm.NewOrm()
+	o.Using("data")
+	sql := ` SELECT * FROM edb_info WHERE edb_info_id=? `
+	err = o.Raw(sql, edbInfoId).QueryRow(&item)
+	return
 }

+ 123 - 0
services/data_manage/data_calculate.go

@@ -0,0 +1,123 @@
+package data_manage
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_task/models/data_manage"
+	"hongze/hongze_task/utils"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/yidane/formula"
+)
+
+//刷新数据
+func RefreshCalculate(edbInfoIdArr []*data_manage.EdbInfo, edbInfoId int, edbCode, formulaStr, startDate, endDate string, edbInfoIdBytes []string) (err error) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Info("Calculate Err:%s" + err.Error())
+		}
+	}()
+	saveDataMap := make(map[string]map[int]float64)
+	for _, v := range edbInfoIdArr {
+		var condition string
+		var pars []interface{}
+		condition += " AND edb_info_id=? "
+		pars = append(pars, v.EdbInfoId)
+		if startDate != "" {
+			condition += " AND data_time>=? "
+			pars = append(pars, startDate)
+		}
+		if endDate != "" {
+			condition += " AND data_time<=? "
+			pars = append(pars, endDate)
+		}
+		dataList, err := data_manage.GetEdbDataListAll(condition, pars, v.Source)
+		if err != nil {
+			return err
+		}
+		dataMap := make(map[string]float64)
+		for _, dv := range dataList {
+			if val, ok := saveDataMap[dv.DataTime]; ok {
+				if _, ok := val[v.EdbInfoId]; !ok {
+					val[v.EdbInfoId] = dv.Value
+				}
+			} else {
+				temp := make(map[int]float64)
+				temp[v.EdbInfoId] = dv.Value
+				saveDataMap[dv.DataTime] = temp
+			}
+		}
+		item := new(CalculateItems)
+		item.EdbInfoId = v.EdbInfoId
+		item.DataMap = dataMap
+	}
+
+	formulaMap := CheckFormula(formulaStr)
+	addSql := ` INSERT INTO edb_data_calculate(edb_info_id,edb_code,data_time,value,create_time,modify_time,status,data_timestamp) values `
+	nowStr := time.Now().Format(utils.FormatDateTime)
+	var isAdd bool
+
+	for sk, sv := range saveDataMap {
+		formulaStr = strings.ToUpper(formulaStr)
+		formulaFormStr := ReplaceFormula(edbInfoIdArr, sv, formulaMap, formulaStr, edbInfoIdBytes)
+		if formulaFormStr != "" {
+			utils.FileLog.Info("formulaFormStr:%s", formulaFormStr)
+			expression := formula.NewExpression(formulaFormStr)
+			calResult, err := expression.Evaluate()
+			if err != nil {
+				err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+				fmt.Println(err)
+				return err
+			}
+			calVal, err := calResult.Float64()
+			if err != nil {
+				err = errors.New("计算失败:获取计算值失败 Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+				fmt.Println(err)
+				return err
+			}
+
+			count, err := data_manage.GetEdbDataCalculateByCodeAndDate(edbCode, sk)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				return err
+			}
+			if count<=0 {//需要存入的数据
+				dataTime, _ := time.Parse(utils.FormatDate, sk)
+				timestamp := dataTime.UnixNano() / 1e6
+				timeStr := fmt.Sprintf("%d", timestamp)
+				addSql += "("
+				addSql += strconv.Itoa(edbInfoId) + "," + "'" + edbCode + "'" + "," + "'" + sk + "'" + "," + utils.SubFloatToString(calVal, 4) + "," + "'" + nowStr + "'" +
+					"," + "'" + nowStr + "'" + "," + "1"
+				addSql += "," + "'" + timeStr + "'"
+				addSql += "),"
+				isAdd = true
+			}else{
+				err = data_manage.ModifyEdbDataCalculate(int64(edbInfoId), sk, calVal)
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		data_manage.AddEdbDataCalculateBySql(addSql)
+		if err != nil {
+			fmt.Println("AddEdbDataCalculate Err:" + err.Error())
+			return err
+		}
+	}
+
+	maxAndMinItem, err := data_manage.GetEdbInfoMaxAndMinInfo(utils.DATA_SOURCE_CALCULATE, edbCode)
+	if err != nil {
+		return err
+	}
+	if maxAndMinItem != nil {
+		err = data_manage.ModifyEdbInfoMaxAndMinInfo(edbInfoId, maxAndMinItem)
+		if err != nil {
+			return err
+		}
+	}
+	return
+}

+ 40 - 0
services/data_manage/edb_info.go

@@ -172,3 +172,43 @@ func CheckPbDataInterface() (err error) {
 	}()
 	return
 }
+
+//刷新计算指标数据
+func RefreshDataFromCalculate() (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("RefreshDataFromCalculate Err:" + err.Error())
+			go utils.SendEmail(utils.APPNAME+"【"+utils.RunMode+"】"+"失败提醒", "RefreshDataFromCalculate ErrMsg:"+err.Error(), utils.EmailSendToUsers)
+		}
+	}()
+	var condition string
+	var pars []interface{}
+	condition += " AND source=? "
+	pars = append(pars, utils.DATA_SOURCE_CALCULATE)
+	items, err := data_manage.GetEdbInfoByCondition(condition, pars)
+	if err != nil {
+		return err
+	}
+	for _, v := range items {
+		startDate := v.EndDate.AddDate(0, 0, -3).Format(utils.FormatDate)
+		endDate := time.Now().Format(utils.FormatDate)
+		var edbInfoIdBytes []string
+		calculateMap, err := data_manage.GetEdbInfoCalculateDetail(int(v.EdbInfoId))
+		if err != nil {
+			return err
+		}
+		var formulaStr string
+		edbInfoList := make([]*data_manage.EdbInfo, 0)
+		for _, v := range calculateMap {
+			formulaStr += v.FromTag + ","
+			edbInfoIdBytes = append(edbInfoIdBytes, v.FromTag)
+			edbInfo, _ := data_manage.GetEdbInfoById(v.EdbInfoId)
+			edbInfoList = append(edbInfoList, edbInfo)
+		}
+		err = RefreshCalculate(edbInfoList, v.EdbInfoId, v.EdbCode, v.CalculateFormula, startDate, endDate, edbInfoIdBytes)
+		if err != nil {
+			return err
+		}
+	}
+	return err
+}

+ 159 - 0
services/data_manage/edb_info_calculate.go

@@ -0,0 +1,159 @@
+package data_manage
+
+import (
+	"fmt"
+	"hongze/hongze_task/models/data_manage"
+	"strings"
+)
+
+type CalculateItems struct {
+	EdbInfoId int
+	DataMap   map[string]float64
+}
+
+
+func CheckFormula(formula string) map[string]string {
+	mathFormula := []string{"MAX", "MIN", "ABS", "ACOS", "ASIN", "CEIL", "MOD", "POW", "ROUND", "SIGN", "SIN", "TAN", "LOG10", "LOG2", "LOG"}
+
+	str := strings.ToUpper(formula)
+	for _, v := range mathFormula {
+		str = strings.Replace(str, v, "", -1)
+	}
+	str = strings.Replace(str, "(", "", -1)
+	str = strings.Replace(str, ")", "", -1)
+
+	byteMap := make(map[string]string)
+	for i := 0; i < len(str); i++ {
+		byteInt := str[i]
+		if byteInt >= 65 && byteInt <= 90 {
+			byteStr := string(byteInt)
+			if _, ok := byteMap[byteStr]; !ok {
+				byteMap[byteStr] = byteStr
+			}
+		}
+	}
+	return byteMap
+}
+
+func ReplaceFormula(edbInfoIdArr []*data_manage.EdbInfo, valArr map[int]float64, formulaMap map[string]string, formulaStr string, edbInfoIdBytes []string) string {
+	funMap := GetFormulaMap()
+	for k, v := range funMap {
+		formulaStr = strings.Replace(formulaStr, k, v, -1)
+	}
+
+	replaceCount := 0
+	for dk, dv := range edbInfoIdArr {
+		if dk == 0 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 1 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 2 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 3 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 4 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 5 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 6 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 7 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+		if dk == 8 {
+			dKey := edbInfoIdBytes[dk]
+			if _, ok := formulaMap[dKey]; ok { //公式中存在
+				if val, valOk := valArr[dv.EdbInfoId]; valOk { //值存在
+					dvStr := fmt.Sprintf("%v", val)
+					formulaStr = strings.Replace(formulaStr, dKey, dvStr, -1)
+					replaceCount++
+				}
+			}
+		}
+	}
+	for k, v := range funMap {
+		formulaStr = strings.Replace(formulaStr, v, k, -1)
+	}
+	if replaceCount == len(formulaMap) {
+		return formulaStr
+	} else {
+		return ""
+	}
+}
+
+func GetFormulaMap() map[string]string {
+	funMap := make(map[string]string)
+	funMap["MAX"] = "[@@]"
+	funMap["MIN"] = "[@!]"
+	funMap["ABS"] = "[@#]"
+	funMap["CEIL"] = "[@$]"
+	funMap["COS"] = "[@%]"
+	funMap["FLOOR"] = "[@^]"
+	funMap["MOD"] = "[@&]"
+	funMap["POW"] = "[@*]"
+	funMap["ROUND"] = "[@(]"
+	return funMap
+}

+ 10 - 3
services/task.go

@@ -84,12 +84,13 @@ func releaseTask(){
 	freeViewerDetail := toolbox.NewTask("freeViewerDetail", "0 0 9 * * 1 ", FreeViewerDetail)
 	toolbox.AddTask("潜在客户", freeViewerDetail)
 
-	//刷新数据
+	//刷新指标数据
 	refreshData := toolbox.NewTask("refreshData", "0 0 18 * * *", RefreshData)
 	toolbox.AddTask("refreshData", refreshData)
 
-	checkDataInterface := toolbox.NewTask("checkDataInterface", "0 */3 * * * * ", data_manage.CheckDataInterface)
-	toolbox.AddTask("checkDataInterface", checkDataInterface)
+	//刷新计算指标数据
+	refreshCalculateData := toolbox.NewTask("refreshCalculateData", "0 10 18 * * *", RefreshCalculateData)
+	toolbox.AddTask("refreshCalculateData", refreshCalculateData)
 
 	checkPbDataInterface := toolbox.NewTask("checkPbDataInterface", "0 */5 * * * * ", data_manage.CheckPbDataInterface)
 	toolbox.AddTask("checkPbDataInterface", checkPbDataInterface)
@@ -140,4 +141,10 @@ func RefreshData() (err error){
 	//彭博
 	go data_manage.RefreshDataFromPb()
 	return
+}
+
+func RefreshCalculateData() (err error){
+	//计算指标
+	go data_manage.RefreshDataFromCalculate()
+	return
 }

+ 4 - 3
utils/constants.go

@@ -63,9 +63,10 @@ const (
 
 //数据来源渠道
 const (
-	DATA_SOURCE_THS  = iota + 1 //同花顺
-	DATA_SOURCE_WIND            //wind
-	DATA_SOURCE_PB              //彭博
+	DATA_SOURCE_THS       = iota + 1 //同花顺
+	DATA_SOURCE_WIND                 //wind
+	DATA_SOURCE_PB                   //彭博
+	DATA_SOURCE_CALCULATE            //计算指标
 )
 
 //http://datawind.hzinsights.com:8040/hz_server