729 lines
17 KiB
Go
729 lines
17 KiB
Go
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
|
|
}
|