Initial commit
This commit is contained in:
@@ -0,0 +1,728 @@
|
||||
package statutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
type Value struct {
|
||||
Value int64 `json:"value" bson:"value"` // Value
|
||||
Count int64 `json:"count" bson:"count"` // Count
|
||||
}
|
||||
|
||||
func (s *Value) CountRef() *int64 {
|
||||
return &s.Count
|
||||
}
|
||||
|
||||
func (s *Value) ValueRef() *int64 {
|
||||
return &s.Value
|
||||
}
|
||||
|
||||
func (s *Value) Add(value int64) {
|
||||
s.Count++
|
||||
s.Value += value
|
||||
}
|
||||
|
||||
func (s *Value) Sub(d *Value) *Value {
|
||||
ret := &Value{
|
||||
Count: s.Count - d.Count,
|
||||
Value: s.Value - d.Value,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Value) Plus(d *Value) *Value {
|
||||
ret := &Value{
|
||||
Count: s.Count + d.Count,
|
||||
Value: s.Value + d.Value,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Value) ACC(d *Value) {
|
||||
s.Count += d.Count
|
||||
s.Value += d.Value
|
||||
}
|
||||
|
||||
func (s *Value) Percentage(den *Value) *Value {
|
||||
ret := &Value{
|
||||
Count: percentageDiv(s.Count, den.Count),
|
||||
Value: percentageDiv(s.Value, den.Value),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Value) Permil(den *Value) *Value {
|
||||
ret := &Value{
|
||||
Count: permilDiv(s.Count, den.Count),
|
||||
Value: permilDiv(s.Value, den.Value),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Value) Mul(v int64) *Value {
|
||||
ret := &Value{
|
||||
Count: s.Count * v,
|
||||
Value: s.Value * v,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type Direct struct {
|
||||
Total Value `json:"total" bson:"total"` // Total
|
||||
Natural Value `json:"natural" bson:"natural"` // Natural
|
||||
}
|
||||
|
||||
func (s *Direct) CountRef() *int64 {
|
||||
return &s.Total.Count
|
||||
}
|
||||
|
||||
func (s *Direct) Count() int64 {
|
||||
return s.Total.Count
|
||||
}
|
||||
|
||||
func (s *Direct) ValueRef() *int64 {
|
||||
return &s.Total.Value
|
||||
}
|
||||
|
||||
func (s *Direct) Value() int64 {
|
||||
return s.Total.Value
|
||||
}
|
||||
|
||||
func (s *Direct) Add(value int64, device *ClientInfo) {
|
||||
s.Total.Add(value)
|
||||
if device.Natural {
|
||||
s.Natural.Add(value)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Direct) Sub(d *Direct) *Direct {
|
||||
ret := &Direct{
|
||||
Total: *s.Total.Sub(&d.Total),
|
||||
Natural: *s.Natural.Sub(&d.Natural),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Direct) Plus(d *Direct) *Direct {
|
||||
ret := &Direct{
|
||||
Total: *s.Total.Plus(&d.Total),
|
||||
Natural: *s.Natural.Plus(&d.Natural),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Direct) ACC(d *Direct) {
|
||||
s.Total.ACC(&d.Total)
|
||||
s.Natural.ACC(&d.Natural)
|
||||
}
|
||||
|
||||
func (s *Direct) Percentage(den *Direct) *Direct {
|
||||
ret := &Direct{
|
||||
Total: *s.Total.Percentage(&den.Total),
|
||||
Natural: *s.Total.Percentage(&den.Total),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Direct) Permil(den *Direct) *Direct {
|
||||
ret := &Direct{
|
||||
Total: *s.Total.Permil(&den.Total),
|
||||
Natural: *s.Natural.Permil(&den.Natural),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Direct) Mul(v int64) *Direct {
|
||||
ret := &Direct{
|
||||
Total: *s.Total.Mul(v),
|
||||
Natural: *s.Natural.Mul(v),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type From struct {
|
||||
Total Value `json:"total" bson:"total"` // Total
|
||||
// ---------------------分类1------------------------
|
||||
Web Value `json:"web" bson:"web"` // 网站
|
||||
Share Value `json:"share" bson:"share"` // 分享
|
||||
Normal Value `json:"normal" bson:"normal"` // 自来
|
||||
District Value `json:"district" bson:"district"` // 渠道
|
||||
// ---------------------分类2------------------------
|
||||
Direct Direct `json:"direct" bson:"direct"` // 直推
|
||||
Fission Value `json:"fission" bson:"fission"` // 裂变
|
||||
Deduction Value `json:"deduction" bson:"deduction"` // 扣量
|
||||
}
|
||||
|
||||
type StatH5 struct {
|
||||
// 总计
|
||||
Total From `json:"total" bson:"total"` // Total = Pc + Ios + Android
|
||||
// 分类1
|
||||
Pc From `json:"h5Pc" bson:"h5Pc"` // H5PC
|
||||
Ios From `json:"h5Ios" bson:"h5Ios"` // H5IOS
|
||||
Android From `json:"h5Android" bson:"h5Android"` // Android
|
||||
// 分类2
|
||||
Guest From `json:"h5Guest" bson:"h5Guest"` // Guest
|
||||
Formal From `json:"h5Formal" bson:"h5Formal"` // H5正式用户
|
||||
}
|
||||
|
||||
func (s *StatH5) Sub(d *StatH5) *StatH5 {
|
||||
ret := &StatH5{
|
||||
Total: *s.Total.Sub(&d.Total),
|
||||
Pc: *s.Pc.Sub(&d.Pc),
|
||||
Ios: *s.Ios.Sub(&d.Ios),
|
||||
Android: *s.Android.Sub(&d.Android),
|
||||
Guest: *s.Guest.Sub(&d.Guest),
|
||||
Formal: *s.Formal.Sub(&d.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatH5) Plus(d *StatH5) *StatH5 {
|
||||
ret := &StatH5{
|
||||
Total: *s.Total.Plus(&d.Total),
|
||||
Pc: *s.Pc.Plus(&d.Pc),
|
||||
Ios: *s.Ios.Plus(&d.Ios),
|
||||
Android: *s.Android.Plus(&d.Android),
|
||||
Guest: *s.Guest.Plus(&d.Guest),
|
||||
Formal: *s.Formal.Plus(&d.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatH5) ACC(d *StatH5) {
|
||||
s.Total.ACC(&d.Total)
|
||||
s.Pc.ACC(&d.Pc)
|
||||
s.Ios.ACC(&d.Ios)
|
||||
s.Android.ACC(&d.Android)
|
||||
s.Guest.ACC(&d.Guest)
|
||||
s.Formal.ACC(&d.Formal)
|
||||
}
|
||||
|
||||
func (s *StatH5) Mul(v int64) *StatH5 {
|
||||
ret := &StatH5{
|
||||
Total: *s.Total.Mul(v),
|
||||
Pc: *s.Pc.Mul(v),
|
||||
Ios: *s.Ios.Mul(v),
|
||||
Android: *s.Android.Mul(v),
|
||||
Guest: *s.Guest.Mul(v),
|
||||
Formal: *s.Formal.Mul(v),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatH5) Add(value int64, device *ClientInfo) {
|
||||
s.Total.Add(value, device)
|
||||
if device.H5Android {
|
||||
s.Android.Add(value, device)
|
||||
} else if device.H5Ios {
|
||||
s.Ios.Add(value, device)
|
||||
} else if device.H5Pc {
|
||||
s.Pc.Add(value, device)
|
||||
}
|
||||
if device.Formal {
|
||||
s.Formal.Add(value, device)
|
||||
} else {
|
||||
s.Guest.Add(value, device)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StatH5) CountRef() *int64 {
|
||||
return s.Total.CountRef()
|
||||
}
|
||||
|
||||
func (s *StatH5) Count() int64 {
|
||||
return s.Total.Count()
|
||||
}
|
||||
|
||||
func (s *StatH5) ValueRef() *int64 {
|
||||
return s.Total.ValueRef()
|
||||
}
|
||||
|
||||
func (s *StatH5) Value() int64 {
|
||||
return s.Total.Value()
|
||||
}
|
||||
|
||||
func (s *StatH5) Percentage(den *StatH5) *StatH5 {
|
||||
ret := &StatH5{
|
||||
Total: *s.Total.Percentage(&den.Total),
|
||||
Pc: *s.Pc.Percentage(&den.Pc),
|
||||
Ios: *s.Ios.Percentage(&den.Ios),
|
||||
Android: *s.Android.Percentage(&den.Android),
|
||||
Guest: *s.Guest.Percentage(&den.Guest),
|
||||
Formal: *s.Formal.Percentage(&den.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatH5) Permil(den *StatH5) *StatH5 {
|
||||
ret := &StatH5{
|
||||
Total: *s.Total.Permil(&den.Total),
|
||||
Pc: *s.Pc.Permil(&den.Pc),
|
||||
Ios: *s.Ios.Permil(&den.Ios),
|
||||
Android: *s.Android.Permil(&den.Android),
|
||||
Guest: *s.Guest.Permil(&den.Guest),
|
||||
Formal: *s.Formal.Permil(&den.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatH5) Rows(div int64, compare *StatH5) [][]string {
|
||||
if div == 0 {
|
||||
div = 1
|
||||
}
|
||||
ret := make([][]string, 0)
|
||||
if compare != nil {
|
||||
ret = append(ret, s.Total.Row("H5总计", div, &compare.Total))
|
||||
ret = append(ret, s.Android.Row("H5安卓", div, &compare.Android))
|
||||
ret = append(ret, s.Ios.Row("H5苹果", div, &compare.Ios))
|
||||
ret = append(ret, s.Pc.Row("H5电脑", div, &compare.Pc))
|
||||
ret = append(ret, s.Guest.Row("H5游客", div, &compare.Guest))
|
||||
ret = append(ret, s.Formal.Row("H5注册", div, &compare.Formal))
|
||||
} else {
|
||||
ret = append(ret, s.Total.Row("H5总计", div, nil))
|
||||
ret = append(ret, s.Android.Row("H5安卓", div, nil))
|
||||
ret = append(ret, s.Ios.Row("H5苹果", div, nil))
|
||||
ret = append(ret, s.Pc.Row("H5电脑", div, nil))
|
||||
ret = append(ret, s.Guest.Row("H5游客", div, nil))
|
||||
ret = append(ret, s.Formal.Row("H5注册", div, nil))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type Stat struct {
|
||||
Total From `json:"total" bson:"total"` // Total
|
||||
Android From `json:"android" bson:"android"` // Android
|
||||
Ios From `json:"ios" bson:"ios"` // IOS
|
||||
Light StatLight `json:"light" bson:"light"` // Light
|
||||
H5 StatH5 `json:"h5" bson:"h5"` // H5
|
||||
}
|
||||
|
||||
func (s *Stat) Mul(v int64) *Stat {
|
||||
ret := &Stat{
|
||||
Total: *s.Total.Mul(v),
|
||||
Android: *s.Android.Mul(v),
|
||||
Ios: *s.Ios.Mul(v),
|
||||
Light: *s.Light.Mul(v),
|
||||
H5: *s.H5.Mul(v),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Stat) Percentage(den *Stat) *Stat {
|
||||
ret := &Stat{
|
||||
Total: *s.Total.Percentage(&den.Total),
|
||||
Android: *s.Android.Percentage(&den.Android),
|
||||
Ios: *s.Ios.Percentage(&den.Ios),
|
||||
Light: *s.Light.Percentage(&den.Light),
|
||||
H5: *s.H5.Percentage(&den.H5),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Stat) Permil(den *Stat) *Stat {
|
||||
ret := &Stat{
|
||||
Total: *s.Total.Permil(&den.Total),
|
||||
Android: *s.Android.Permil(&den.Android),
|
||||
Ios: *s.Ios.Permil(&den.Ios),
|
||||
Light: *s.Light.Permil(&den.Light),
|
||||
H5: *s.H5.Permil(&den.H5),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Stat) Sub(d *Stat) *Stat {
|
||||
ret := &Stat{
|
||||
Total: *s.Total.Sub(&d.Total),
|
||||
Android: *s.Android.Sub(&d.Android),
|
||||
Ios: *s.Ios.Sub(&d.Ios),
|
||||
Light: *s.Light.Sub(&d.Light),
|
||||
H5: *s.H5.Sub(&d.H5),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Stat) Plus(d *Stat) *Stat {
|
||||
ret := &Stat{
|
||||
Total: *s.Total.Plus(&d.Total),
|
||||
Android: *s.Android.Plus(&d.Android),
|
||||
Ios: *s.Ios.Plus(&d.Ios),
|
||||
Light: *s.Light.Plus(&d.Light),
|
||||
H5: *s.H5.Plus(&d.H5),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *Stat) ACC(d *Stat) {
|
||||
s.Total.ACC(&d.Total)
|
||||
s.Android.ACC(&d.Android)
|
||||
s.Ios.ACC(&d.Ios)
|
||||
s.Light.ACC(&d.Light)
|
||||
s.H5.ACC(&d.H5)
|
||||
}
|
||||
|
||||
func (s *Stat) Add(value int64, device *ClientInfo) {
|
||||
s.Total.Add(value, device)
|
||||
if device.Android {
|
||||
s.Android.Add(value, device)
|
||||
} else if device.Ios {
|
||||
s.Ios.Add(value, device)
|
||||
} else if device.Light {
|
||||
s.Light.Add(value, device)
|
||||
} else if device.H5 {
|
||||
s.H5.Add(value, device)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Stat) CountRef() *int64 {
|
||||
return s.Total.CountRef()
|
||||
}
|
||||
|
||||
func (s *Stat) Count() int64 {
|
||||
return s.Total.Count()
|
||||
}
|
||||
|
||||
func (s *Stat) ValueRef() *int64 {
|
||||
return s.Total.ValueRef()
|
||||
}
|
||||
|
||||
func (s *Stat) Value() int64 {
|
||||
return s.Total.Value()
|
||||
}
|
||||
|
||||
func (s *Stat) Rows(div int64, compare *Stat) [][]string {
|
||||
if div == 0 {
|
||||
div = 1
|
||||
}
|
||||
ret := make([][]string, 0)
|
||||
if compare != nil {
|
||||
ret = append(ret, s.Android.Row("安卓", div, &compare.Android))
|
||||
ret = append(ret, s.Ios.Row("苹果", div, &compare.Ios))
|
||||
ret = append(ret, s.Light.Rows(div, &compare.Light)...)
|
||||
ret = append(ret, s.H5.Rows(div, &compare.H5)...)
|
||||
ret = append(ret, s.Total.Row("合计", div, &compare.Total))
|
||||
} else {
|
||||
ret = append(ret, s.Android.Row("安卓", div, nil))
|
||||
ret = append(ret, s.Ios.Row("苹果", div, nil))
|
||||
ret = append(ret, s.Light.Rows(div, nil)...)
|
||||
ret = append(ret, s.H5.Rows(div, nil)...)
|
||||
ret = append(ret, s.Total.Row("合计", div, nil))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) Sub(d *From) *From {
|
||||
ret := &From{
|
||||
Total: *s.Total.Sub(&d.Total),
|
||||
Web: *s.Web.Sub(&d.Web),
|
||||
Normal: *s.Normal.Sub(&d.Normal),
|
||||
District: *s.District.Sub(&d.District),
|
||||
Share: *s.Share.Sub(&d.Share),
|
||||
Direct: *s.Direct.Sub(&d.Direct),
|
||||
Fission: *s.Fission.Sub(&d.Fission),
|
||||
Deduction: *s.Deduction.Sub(&d.Deduction),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) Plus(d *From) *From {
|
||||
ret := &From{
|
||||
Total: *s.Total.Plus(&d.Total),
|
||||
Web: *s.Web.Plus(&d.Web),
|
||||
Normal: *s.Normal.Plus(&d.Normal),
|
||||
District: *s.District.Plus(&d.District),
|
||||
Share: *s.Share.Plus(&d.Share),
|
||||
Direct: *s.Direct.Plus(&d.Direct),
|
||||
Fission: *s.Fission.Plus(&d.Fission),
|
||||
Deduction: *s.Deduction.Plus(&d.Deduction),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) ACC(d *From) {
|
||||
s.Total.ACC(&d.Total)
|
||||
s.Web.ACC(&d.Web)
|
||||
s.Normal.ACC(&d.Normal)
|
||||
s.District.ACC(&d.District)
|
||||
s.Share.ACC(&d.Share)
|
||||
s.Direct.ACC(&d.Direct)
|
||||
s.Fission.ACC(&d.Fission)
|
||||
s.Deduction.ACC(&d.Deduction)
|
||||
}
|
||||
|
||||
func (s *From) Mul(v int64) *From {
|
||||
ret := &From{
|
||||
Total: *s.Total.Mul(v),
|
||||
Web: *s.Web.Mul(v),
|
||||
Normal: *s.Normal.Mul(v),
|
||||
District: *s.District.Mul(v),
|
||||
Share: *s.Share.Mul(v),
|
||||
Direct: *s.Direct.Mul(v),
|
||||
Fission: *s.Fission.Mul(v),
|
||||
Deduction: *s.Deduction.Mul(v),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) Percentage(den *From) *From {
|
||||
ret := &From{
|
||||
Total: *s.Total.Percentage(&den.Total),
|
||||
Web: *s.Web.Percentage(&den.Web),
|
||||
Normal: *s.Normal.Percentage(&den.Normal),
|
||||
District: *s.District.Percentage(&den.District),
|
||||
Share: *s.Share.Percentage(&den.Share),
|
||||
Direct: *s.Direct.Percentage(&den.Direct),
|
||||
Fission: *s.Fission.Percentage(&den.Fission),
|
||||
Deduction: *s.Deduction.Percentage(&den.Deduction),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) Permil(den *From) *From {
|
||||
ret := &From{
|
||||
Total: *s.Total.Permil(&den.Total),
|
||||
Web: *s.Web.Permil(&den.Web),
|
||||
Normal: *s.Normal.Permil(&den.Normal),
|
||||
District: *s.District.Permil(&den.District),
|
||||
Share: *s.Share.Permil(&den.Share),
|
||||
Direct: *s.Direct.Permil(&den.Direct),
|
||||
Fission: *s.Fission.Permil(&den.Fission),
|
||||
Deduction: *s.Deduction.Permil(&den.Deduction),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *From) Row(title string, div int64, compare *From) []string {
|
||||
if div == 0 {
|
||||
div = 1
|
||||
}
|
||||
if compare == nil {
|
||||
return []string{
|
||||
title,
|
||||
fmt.Sprintf("%d", s.Total.Value/div),
|
||||
fmt.Sprintf("%d", s.Web.Value/div),
|
||||
fmt.Sprintf("%d", s.Normal.Value/div),
|
||||
fmt.Sprintf("%d", s.District.Value/div),
|
||||
fmt.Sprintf("%d", s.Share.Value/div),
|
||||
fmt.Sprintf("%d", s.Direct.Total.Value/div),
|
||||
fmt.Sprintf("%d", s.Fission.Value/div),
|
||||
fmt.Sprintf("%d", s.Deduction.Value/div),
|
||||
}
|
||||
} else {
|
||||
diff := s.Sub(compare)
|
||||
rate := diff.Permil(compare)
|
||||
return []string{
|
||||
title,
|
||||
fmt.Sprintf("%d\n%s", s.Total.Value/div, DisplayPermilToPercentage(rate.Total.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Web.Value/div, DisplayPermilToPercentage(rate.Web.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Normal.Value/div, DisplayPermilToPercentage(rate.Normal.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.District.Value/div, DisplayPermilToPercentage(rate.District.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Share.Value/div, DisplayPermilToPercentage(rate.Share.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Direct.Total.Value/div, DisplayPermilToPercentage(rate.Direct.Total.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Fission.Value/div, DisplayPermilToPercentage(rate.Fission.Value)),
|
||||
fmt.Sprintf("%d\n%s", s.Deduction.Value/div, DisplayPermilToPercentage(rate.Deduction.Value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *From) Header(title string) []string {
|
||||
return []string{title, "总量", "官网", "自来", "渠道", "分享", "直推", "裂变", "扣量"}
|
||||
}
|
||||
|
||||
func (s *From) Add(value int64, client *ClientInfo) {
|
||||
s.Total.Add(value)
|
||||
// 分类1统计
|
||||
if client.Web {
|
||||
s.Web.Add(value)
|
||||
} else if client.Share {
|
||||
s.Share.Add(value)
|
||||
} else if client.Normal {
|
||||
s.Normal.Add(value)
|
||||
} else if client.District {
|
||||
s.District.Add(value)
|
||||
}
|
||||
// 分类2统计
|
||||
if client.Deduction {
|
||||
s.Deduction.Add(value)
|
||||
} else {
|
||||
if client.Direct {
|
||||
s.Direct.Add(value, client)
|
||||
} else {
|
||||
s.Fission.Add(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *From) CountRef() *int64 {
|
||||
return s.Total.CountRef()
|
||||
}
|
||||
|
||||
func (s *From) Count() int64 {
|
||||
return s.Total.Count
|
||||
}
|
||||
|
||||
func (s *From) ValueRef() *int64 {
|
||||
return s.Total.ValueRef()
|
||||
}
|
||||
|
||||
func (s *From) Value() int64 {
|
||||
return s.Total.Value
|
||||
}
|
||||
|
||||
func percentageDiv(num, den int64) int64 {
|
||||
if num == 0 {
|
||||
return 0
|
||||
} else {
|
||||
if den == 0 {
|
||||
return math.MaxInt64
|
||||
} else {
|
||||
return num * 100 / den
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func permilDiv(num, den int64) int64 {
|
||||
if num == 0 {
|
||||
return 0
|
||||
} else {
|
||||
if den == 0 {
|
||||
return math.MaxInt64
|
||||
} else {
|
||||
return num * 1000 / den
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DisplayPermilToPercentage(v int64) string {
|
||||
var ret string
|
||||
var x float64
|
||||
if v == math.MaxInt64 {
|
||||
s := "##.##"
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
return ret
|
||||
}
|
||||
if v < -99999 {
|
||||
s := "--.--"
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
return ret
|
||||
}
|
||||
if v > 99999 {
|
||||
s := "++.++"
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
return ret
|
||||
}
|
||||
if v < 0 {
|
||||
x = float64(v) / -10.0
|
||||
s := fmt.Sprintf("-%.1f%%", x)
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
} else if v > 0 {
|
||||
x = float64(v) / 10.0
|
||||
s := fmt.Sprintf("+%.1f%%", x)
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
} else {
|
||||
s := "00.0%"
|
||||
ret = fmt.Sprintf("%s", s)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type StatLight struct {
|
||||
// 总计
|
||||
Total From `json:"total" bson:"total"` // Total = Pc + Ios + Android
|
||||
// 分类
|
||||
Guest From `json:"guest" bson:"guest"` // Guest
|
||||
Formal From `json:"formal" bson:"formal"` // 正式用户
|
||||
}
|
||||
|
||||
func (s *StatLight) Sub(d *StatLight) *StatLight {
|
||||
ret := &StatLight{
|
||||
Total: *s.Total.Sub(&d.Total),
|
||||
Guest: *s.Guest.Sub(&d.Guest),
|
||||
Formal: *s.Formal.Sub(&d.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatLight) Plus(d *StatLight) *StatLight {
|
||||
ret := &StatLight{
|
||||
Total: *s.Total.Plus(&d.Total),
|
||||
Guest: *s.Guest.Plus(&d.Guest),
|
||||
Formal: *s.Formal.Plus(&d.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatLight) ACC(d *StatLight) {
|
||||
s.Total.ACC(&d.Total)
|
||||
s.Guest.ACC(&d.Guest)
|
||||
s.Formal.ACC(&d.Formal)
|
||||
}
|
||||
|
||||
func (s *StatLight) Mul(v int64) *StatLight {
|
||||
ret := &StatLight{
|
||||
Total: *s.Total.Mul(v),
|
||||
Guest: *s.Guest.Mul(v),
|
||||
Formal: *s.Formal.Mul(v),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatLight) Add(value int64, device *ClientInfo) {
|
||||
s.Total.Add(value, device)
|
||||
if device.Formal {
|
||||
s.Formal.Add(value, device)
|
||||
} else {
|
||||
s.Guest.Add(value, device)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StatLight) CountRef() *int64 {
|
||||
return s.Total.CountRef()
|
||||
}
|
||||
|
||||
func (s *StatLight) Count() int64 {
|
||||
return s.Total.Count()
|
||||
}
|
||||
|
||||
func (s *StatLight) ValueRef() *int64 {
|
||||
return s.Total.ValueRef()
|
||||
}
|
||||
|
||||
func (s *StatLight) Value() int64 {
|
||||
return s.Total.Value()
|
||||
}
|
||||
|
||||
func (s *StatLight) Percentage(den *StatLight) *StatLight {
|
||||
ret := &StatLight{
|
||||
Total: *s.Total.Percentage(&den.Total),
|
||||
Guest: *s.Guest.Percentage(&den.Guest),
|
||||
Formal: *s.Formal.Percentage(&den.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatLight) Permil(den *StatLight) *StatLight {
|
||||
ret := &StatLight{
|
||||
Total: *s.Total.Permil(&den.Total),
|
||||
Guest: *s.Guest.Permil(&den.Guest),
|
||||
Formal: *s.Formal.Permil(&den.Formal),
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *StatLight) Rows(div int64, compare *StatLight) [][]string {
|
||||
if div == 0 {
|
||||
div = 1
|
||||
}
|
||||
ret := make([][]string, 0)
|
||||
if compare != nil {
|
||||
ret = append(ret, s.Total.Row("轻量合计", div, &compare.Total))
|
||||
ret = append(ret, s.Guest.Row("轻量安装", div, &compare.Guest))
|
||||
ret = append(ret, s.Formal.Row("轻量注册", div, &compare.Formal))
|
||||
} else {
|
||||
ret = append(ret, s.Total.Row("轻量合计", div, nil))
|
||||
ret = append(ret, s.Guest.Row("轻量安装", div, nil))
|
||||
ret = append(ret, s.Formal.Row("轻量注册", div, nil))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user