From 54c6ab7f30e5a0dafbf6df03622c7ce8f8e11485 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Tue, 5 Nov 2024 16:27:14 +0800 Subject: [PATCH 1/5] fix: tiimestamp issue for customized kpi --- features/pm/kpi_c_report/controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/pm/kpi_c_report/controller.go b/features/pm/kpi_c_report/controller.go index 1b88013c..b161fba2 100644 --- a/features/pm/kpi_c_report/controller.go +++ b/features/pm/kpi_c_report/controller.go @@ -40,11 +40,11 @@ func (k *KpiCReport) Get(c *gin.Context) { return } if querys.StartTime != "" { - conditions = append(conditions, "created_at >= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) >= ?") params = append(params, querys.StartTime) } if querys.EndTime != "" { - conditions = append(conditions, "created_at <= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) <= ?") params = append(params, querys.EndTime) } From 64cd68d5b03fd6bfc6d2543bba840c05f4dbfaf4 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Tue, 5 Nov 2024 16:44:42 +0800 Subject: [PATCH 2/5] fix: kpi_report and kpi_c_report update --- misc/importdb.sh | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/misc/importdb.sh b/misc/importdb.sh index d3c08a73..6a74cd95 100755 --- a/misc/importdb.sh +++ b/misc/importdb.sh @@ -119,17 +119,31 @@ esac # create kpi_report table with ne_type, exp: kpi_report_amf ne_types=$(mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -se "SELECT DISTINCT LOWER(ne_type) FROM kpi_title") for ne_type in ${ne_types}; do - TABLE_NAME="kpi_report_${ne_type}" - SQL="CREATE TABLE IF NOT EXISTS ${TABLE_NAME} AS SELECT * FROM kpi_report WHERE 1=0;ALTER TABLE ${TABLE_NAME} MODIFY COLUMN \`id\` int(11) NOT NULL AUTO_INCREMENT FIRST,ADD PRIMARY KEY IF NOT EXISTS (\`id\`);" - echo -n "Create table: ${TABLE_NAME} ..." - mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -e "${SQL}" - if [ $? = 0 ]; then - echo "done" - fi - SQL="ALTER TABLE ${TABLE_NAME} ADD INDEX IF NOT EXISTS \`idx_timestamp\`(\`created_at\`) USING BTREE, ADD INDEX IF NOT EXISTS \`idx_uid_datetime\`(\`rm_uid\`, \`date\`, \`start_time\`) USING BTREE;" - echo -n "Create index of ${TABLE_NAME} ..." - mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -e "${SQL}" - if [ $? = 0 ]; then - echo "done" - fi + TABLE_NAME="kpi_report_${ne_type}" + SQL="CREATE TABLE IF NOT EXISTS ${TABLE_NAME} LIKE \`kpi_report\`;" + echo -n "Create table: ${TABLE_NAME} ..." + mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -e "${SQL}" + if [ $? = 0 ]; then + echo "done" + fi + SQL="ALTER TABLE ${TABLE_NAME} ADD INDEX IF NOT EXISTS \`idx_timestamp\`(\`created_at\`) USING BTREE, ADD INDEX IF NOT EXISTS \`idx_uid_datetime\`(\`rm_uid\`, \`date\`, \`start_time\`) USING BTREE;" + echo -n "Create index of ${TABLE_NAME} ..." + mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -e "${SQL}" + if [ $? = 0 ]; then + echo "done" + fi + SQL="ALTER TABLE ${TABLE_NAME} ADD INDEX IF NOT EXISTS \`idx_timestamp\`(\`created_at\`) USING BTREE,ADD INDEX IF NOT EXISTS \`idx_uid_datetime\`(\`rm_uid\`, \`date\`, \`start_time\`) USING BTREE;" + echo -n "Create index of ${TABLE_NAME} ..." + mysql -u${USER} -p${PASSWORD} -P ${PORT} --protocol tcp -D ${DBNAME} -e "${SQL}" + if [ $? = 0 ]; then + echo "done" + fi + + TABLE_NAME="kpi_c_report_${ne_type}" + SQL="CREATE TABLE IF NOT EXISTS ${TABLE_NAME} LIKE \`kpi_c_report\`;" + echo -n "Create table: ${TABLE_NAME} ..." + mysql -u${USER} -p${PASSWORD} -P ${PORT} -h ${HOST} --protocol tcp -D ${DBNAME} -e "${SQL}" + if [ $? = 0 ]; then + echo "done" + fi done \ No newline at end of file From 802210cb7d1b08c54d39f804b3c6dc014b3318b0 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Wed, 6 Nov 2024 17:19:17 +0800 Subject: [PATCH 3/5] fix: customized kpi features issues --- features/pm/kpi_c_report/controller.go | 12 +++++----- features/pm/kpi_c_title/controller.go | 32 +++++++++++++++++++++++++- features/pm/kpi_c_title/model.go | 4 ++++ lib/eval/evaluate.go | 8 +++++++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/features/pm/kpi_c_report/controller.go b/features/pm/kpi_c_report/controller.go index b161fba2..a19646b3 100644 --- a/features/pm/kpi_c_report/controller.go +++ b/features/pm/kpi_c_report/controller.go @@ -106,11 +106,11 @@ func (k *KpiCReport) GetReport2FE(c *gin.Context) { return } if querys.StartTime != "" { - conditions = append(conditions, "created_at >= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) >= ?") params = append(params, querys.StartTime) } if querys.EndTime != "" { - conditions = append(conditions, "created_at <= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) <= ?") params = append(params, querys.EndTime) } @@ -185,11 +185,11 @@ func (k *KpiCReport) GetTotalList(c *gin.Context) { dbg := dborm.DefaultDB().Table(tableName) if querys.StartTime != "" { - conditions = append(conditions, "created_at >= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) >= ?") params = append(params, querys.StartTime) } if querys.EndTime != "" { - conditions = append(conditions, "created_at <= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) <= ?") params = append(params, querys.EndTime) } @@ -253,11 +253,11 @@ func (k *KpiCReport) Total(c *gin.Context) { dbg := dborm.DefaultDB().Table(tableName) if querys.StartTime != "" { - conditions = append(conditions, "created_at >= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) >= ?") params = append(params, querys.StartTime) } if querys.EndTime != "" { - conditions = append(conditions, "created_at <= ?") + conditions = append(conditions, "(UNIX_TIMESTAMP(created_at) * 1000) <= ?") params = append(params, querys.EndTime) } diff --git a/features/pm/kpi_c_title/controller.go b/features/pm/kpi_c_title/controller.go index aa2912ce..9e6cf571 100644 --- a/features/pm/kpi_c_title/controller.go +++ b/features/pm/kpi_c_title/controller.go @@ -3,10 +3,12 @@ package kpi_c_title import ( "fmt" "net/http" + "strconv" "strings" "be.ems/lib/dborm" "be.ems/lib/services" + "be.ems/src/framework/utils/ctx" "github.com/gin-gonic/gin" ) @@ -120,17 +122,45 @@ func (k *KpiCTitle) Total(c *gin.Context) { } func (k *KpiCTitle) Post(c *gin.Context) { - var title KpiCTitle + var title, res KpiCTitle if err := c.ShouldBindJSON(&title); err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return } + userName := ctx.LoginUserToUserName(c) + title.CreatedBy = &userName result := dborm.DefaultDB().Where("ne_type=? and (kpi_id=? or title=?)", title.NeType, title.KpiID, title.Title).First(&title) if result.RowsAffected > 0 { c.JSON(http.StatusOK, services.ErrResp("custom indicator already exist")) return } + ret := dborm.DefaultDB().Table("kpi_c_title").Where("ne_type=? ORDER BY kpi_id DESC LIMIT 1", title.NeType).Scan(&res) + if err := ret.Error; err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + newKpiID := *title.NeType + ".C" + ".01" + if ret.RowsAffected != 0 { + maxKpiID := *res.KpiID + prefix := maxKpiID[:len(maxKpiID)-2] + suffix := maxKpiID[len(maxKpiID)-2:] + suffixInt, err := strconv.Atoi(suffix) + if err != nil { + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + if suffixInt >= MAX_KPI_C_ID { + err := fmt.Errorf("exceed the max customized KPI ID") + c.JSON(http.StatusOK, services.ErrResp(err.Error())) + return + } + + suffixInt++ + newSuffix := fmt.Sprintf("%02d", suffixInt) + newKpiID = prefix + newSuffix + } + title.KpiID = &newKpiID if err := dborm.DefaultDB().Create(&title).Error; err != nil { c.JSON(http.StatusOK, services.ErrResp(err.Error())) return diff --git a/features/pm/kpi_c_title/model.go b/features/pm/kpi_c_title/model.go index 77bb9423..fb6ff46c 100644 --- a/features/pm/kpi_c_title/model.go +++ b/features/pm/kpi_c_title/model.go @@ -2,6 +2,10 @@ package kpi_c_title import "time" +const ( + MAX_KPI_C_ID = 99 +) + type KpiCTitle struct { ID int `gorm:"column:id;primary_key;auto_increment" json:"id"` NeType *string `gorm:"column:ne_type;default:NULL," json:"neType,omitempty"` diff --git a/lib/eval/evaluate.go b/lib/eval/evaluate.go index d0ff37e0..664d7176 100644 --- a/lib/eval/evaluate.go +++ b/lib/eval/evaluate.go @@ -5,6 +5,7 @@ import ( "go/ast" "go/parser" "go/token" + "math" "regexp" "strconv" "strings" @@ -29,6 +30,9 @@ func CalcExpr(expr string, paramValues map[string]any) (float64, error) { // expression to evaluate result, err := evalExpr(expr) + if math.IsNaN(result) { + return 0.0, err + } return result, err } @@ -87,6 +91,10 @@ func evalNode(node ast.Node) (float64, error) { case token.MUL: result = left * right case token.QUO: + if right == 0 { + return math.NaN(), fmt.Errorf("divisor cannot be zero") + } + result = left / right } case *ast.BasicLit: From 1efbae9a4d371419352ecc67ca52f2e14a57e299 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Fri, 8 Nov 2024 11:25:20 +0800 Subject: [PATCH 4/5] add: return expression alias while get customized kpi list --- features/pm/kpi_c_title/controller.go | 33 +++++++++++++++++++++++++++ features/pm/kpi_c_title/model.go | 1 + 2 files changed, 34 insertions(+) diff --git a/features/pm/kpi_c_title/controller.go b/features/pm/kpi_c_title/controller.go index 9e6cf571..380d4665 100644 --- a/features/pm/kpi_c_title/controller.go +++ b/features/pm/kpi_c_title/controller.go @@ -3,10 +3,12 @@ package kpi_c_title import ( "fmt" "net/http" + "regexp" "strconv" "strings" "be.ems/lib/dborm" + "be.ems/lib/log" "be.ems/lib/services" "be.ems/src/framework/utils/ctx" "github.com/gin-gonic/gin" @@ -16,6 +18,7 @@ func (k *KpiCTitle) GetToalList(c *gin.Context) { var titles []KpiCTitle var conditions []string var params []any + i18n := ctx.AcceptLanguage(c) var querys KpiCTitleQuery if err := c.ShouldBindQuery(&querys); err != nil { @@ -64,6 +67,8 @@ func (k *KpiCTitle) GetToalList(c *gin.Context) { return } + k.expressionAlias(titles, i18n) + c.JSON(http.StatusOK, services.TotalDataResp(titles, total)) //c.JSON(http.StatusOK, titles) } @@ -72,6 +77,7 @@ func (k *KpiCTitle) Get(c *gin.Context) { var titles []KpiCTitle var conditions []string var params []any + i18n := ctx.AcceptLanguage(c) // construct condition to get if neType := c.Query("neType"); neType != "" { @@ -91,10 +97,37 @@ func (k *KpiCTitle) Get(c *gin.Context) { return } + k.expressionAlias(titles, i18n) + c.JSON(http.StatusOK, services.DataResp(titles)) //c.JSON(http.StatusOK, titles) } +func (k *KpiCTitle) expressionAlias(titles []KpiCTitle, i18n string) { + var title *KpiCTitle + for i := 0; i < len(titles); i++ { + title = &titles[i] + title.ExprAlias = *title.Expression + re := regexp.MustCompile(`'([^']+)'`) + matches := re.FindAllStringSubmatch(title.ExprAlias, -1) + + for _, match := range matches { + var alias, sql string + if i18n == "zh" { + sql = fmt.Sprintf("SELECT cn_title FROM kpi_title WHERE kpi_id='%s'", match[1]) + } else { + sql = fmt.Sprintf("SELECT en_title FROM kpi_title WHERE kpi_id='%s'", match[1]) + } + err := dborm.XCoreDB().QueryRow(sql).Scan(&alias) + if err != nil { + log.Warn("Failed to QueryRow:", err) + continue + } + title.ExprAlias = regexp.MustCompile(match[1]).ReplaceAllString(title.ExprAlias, alias) + } + } +} + func (k *KpiCTitle) Total(c *gin.Context) { var conditions []string var params []any diff --git a/features/pm/kpi_c_title/model.go b/features/pm/kpi_c_title/model.go index fb6ff46c..cdc2b5cc 100644 --- a/features/pm/kpi_c_title/model.go +++ b/features/pm/kpi_c_title/model.go @@ -12,6 +12,7 @@ type KpiCTitle struct { KpiID *string `gorm:"column:kpi_id;default:NULL," json:"kpiId,omitempty"` Title *string `gorm:"column:title;default:NULL," json:"title,omitempty"` Expression *string `gorm:"column:expression;default:NULL," json:"expression,omitempty"` + ExprAlias string `gorm:"-" json:"exprAlias"` Status string `gorm:"column:status;default:'Active'" json:"status"` Unit *string `gorm:"column:unit" json:"unit,omitempty"` Description *string `gorm:"column:description;default:NULL," json:"description,omitempty"` From 395ebb05f9e525e264b77c28ad75f211087d58f4 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Fri, 8 Nov 2024 15:45:22 +0800 Subject: [PATCH 5/5] update comment --- features/pm/kpi_c_title/controller.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/pm/kpi_c_title/controller.go b/features/pm/kpi_c_title/controller.go index 380d4665..c787460f 100644 --- a/features/pm/kpi_c_title/controller.go +++ b/features/pm/kpi_c_title/controller.go @@ -14,6 +14,7 @@ import ( "github.com/gin-gonic/gin" ) +// get customize kpi total and list func (k *KpiCTitle) GetToalList(c *gin.Context) { var titles []KpiCTitle var conditions []string @@ -103,6 +104,7 @@ func (k *KpiCTitle) Get(c *gin.Context) { //c.JSON(http.StatusOK, titles) } +// alias customized kpi expression with cn/en title func (k *KpiCTitle) expressionAlias(titles []KpiCTitle, i18n string) { var title *KpiCTitle for i := 0; i < len(titles); i++ {