You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
6.5 KiB
240 lines
6.5 KiB
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
"github.com/gogf/gf/v2/os/gtime"
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
"time"
|
|
v1 "vistor/api/v1"
|
|
"vistor/internal/consts"
|
|
"vistor/internal/dao"
|
|
"vistor/internal/model"
|
|
)
|
|
|
|
type visitorService struct{}
|
|
|
|
var Visitor = visitorService{}
|
|
|
|
//var statisticType = g.Map{
|
|
// "day":
|
|
//}
|
|
|
|
type IVisitor interface {
|
|
VisitorAccess(ctx context.Context, req *v1.VisitorAccessReq) error
|
|
VisitorStatistic(ctx context.Context, req *v1.VisitorAccessReq) (res *v1.VisitorAccessRes, err error)
|
|
}
|
|
|
|
func (s *visitorService) VisitorAccess(ctx context.Context, req *v1.VisitorAccessReq) error {
|
|
insert, err := dao.VisitorRecord.Ctx(ctx).Data(req).Insert()
|
|
|
|
affected, err := insert.RowsAffected()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if affected == 0 {
|
|
return gerror.Newf("提交失败,请重试")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *visitorService) VisitorStatistic(ctx context.Context, req *v1.VisitorStatisticReq) (res *v1.VisitorStatisticRes, err error) {
|
|
var (
|
|
resRecords []*model.ResRecord
|
|
)
|
|
db := g.DB()
|
|
xAxis := g.SliceStr{}
|
|
yAxis := g.SliceStr{}
|
|
|
|
condition := g.Map{}
|
|
if req.VisitorName != "" {
|
|
condition["vr.visitor_name"] = req.VisitorName
|
|
}
|
|
|
|
if req.VisitorIdentity != "" {
|
|
condition["vr.visitor_identity"] = req.VisitorIdentity
|
|
}
|
|
|
|
if req.VisitorPhone != "" {
|
|
condition["vr.visitor_phone"] = req.VisitorPhone
|
|
}
|
|
|
|
if req.StatisticType == consts.StatisticTypeDay {
|
|
startDate := gconv.Int(gtime.New(req.EndDate).Format("Ymd"))
|
|
endDate := gconv.Int(gtime.New(req.StartDate).Format("Ymd"))
|
|
|
|
duration := startDate - endDate + 1
|
|
|
|
for i := 0; duration > i; i++ {
|
|
xAxis = append(xAxis, gtime.New(req.StartDate).AddDate(0, 0, i).Format("Y-m-d"))
|
|
}
|
|
|
|
fields := "id,visitor_name,visitor_identity,visitor_phone,visit_at,from_unixtime(visit_at,'%Y-%m-%d') visit_date"
|
|
subQuery := db.Model("visitor_record vr").
|
|
Where(condition).
|
|
WhereBetween("vr.visit_at", req.StartDate, req.EndDate).
|
|
Fields(fields)
|
|
|
|
mainQuery := db.Model("? as v", subQuery)
|
|
err = mainQuery.
|
|
Fields("count(v.id) y_axis, v.visit_date x_axis").
|
|
Group("x_axis").
|
|
Order("x_axis").
|
|
Scan(&resRecords)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, x := range xAxis {
|
|
y := "0"
|
|
for _, record := range resRecords {
|
|
if record.XAxis == x {
|
|
y = record.YAxis
|
|
}
|
|
}
|
|
yAxis = append(yAxis, y)
|
|
}
|
|
} else {
|
|
var weekNum, monthNum, yearNum int
|
|
|
|
if req.StatisticType == consts.StatisticTypeWeek {
|
|
switch req.SubType {
|
|
case consts.SubTypeLastWeek:
|
|
weekNum = 1
|
|
case consts.SubTypeLast2Week:
|
|
weekNum = 2
|
|
case consts.SubTypeLast3Week:
|
|
weekNum = 3
|
|
}
|
|
//获取按周统计数据
|
|
xAxis, yAxis = s.getWeekStatistic(ctx, weekNum, condition)
|
|
} else if req.StatisticType == consts.StatisticTypeMonth {
|
|
switch req.SubType {
|
|
case consts.SubTypeLast3Month:
|
|
monthNum = 3
|
|
case consts.SubTypeLast6Month:
|
|
monthNum = 6
|
|
case consts.SubTypeLast9Month:
|
|
monthNum = 9
|
|
}
|
|
//获取按月统计数据
|
|
xAxis, yAxis = s.getMonthStatistic(ctx, monthNum, condition)
|
|
} else if req.StatisticType == consts.StatisticTypeYear {
|
|
switch req.SubType {
|
|
case consts.SubTypeLastYear:
|
|
yearNum = 1
|
|
case consts.SubTypeLast2Year:
|
|
yearNum = 2
|
|
case consts.SubTypeLast3Year:
|
|
yearNum = 3
|
|
}
|
|
//获取按年统计数据
|
|
xAxis, yAxis = s.getYearStatistic(ctx, yearNum, condition)
|
|
}
|
|
|
|
}
|
|
|
|
res = &v1.VisitorStatisticRes{
|
|
XAxis: xAxis,
|
|
YAxis: yAxis,
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *visitorService) getYearStatistic(ctx context.Context, lastYearNum int, condition g.Map) (xAxis g.SliceStr, yAxis g.SliceStr) {
|
|
for ; 1 <= lastYearNum; lastYearNum-- {
|
|
//获取当年第一天
|
|
yearStart := gtime.New(gtime.Now().AddDate(-(lastYearNum - 1), 0, 0).Format("Y-01-01 00:00:00")).Unix()
|
|
yearEnd := gtime.New(gtime.Now().AddDate(-(lastYearNum - 2), 0, 0).Format("Y-01-01 00:00:00")).Unix()
|
|
|
|
count, err := dao.VisitorRecord.Ctx(ctx).As("vr").Where(condition).WhereBetween(dao.VisitorRecord.Columns().VisitAt, yearStart, yearEnd).Count()
|
|
if err != nil {
|
|
return g.SliceStr{}, g.SliceStr{}
|
|
}
|
|
|
|
//获取统计数据
|
|
xAxis = append(xAxis, gtime.New(yearStart).Format("Y"))
|
|
yAxis = append(yAxis, gconv.String(count))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *visitorService) getMonthStatistic(ctx context.Context, lastMonthNum int, condition g.Map) (xAxis g.SliceStr, yAxis g.SliceStr) {
|
|
for ; 1 <= lastMonthNum; lastMonthNum-- {
|
|
//获取当月第一天
|
|
monthStart := gtime.New(gtime.Now().AddDate(0, -(lastMonthNum - 1), 0).Format("Y-m-01 00:00:00")).Unix()
|
|
monthEnd := gtime.New(gtime.Now().AddDate(0, -(lastMonthNum - 2), 0).Format("Y-m-01 00:00:00")).Unix()
|
|
|
|
count, err := dao.VisitorRecord.Ctx(ctx).As("vr").Where(condition).WhereBetween(dao.VisitorRecord.Columns().VisitAt, monthStart, monthEnd).Count()
|
|
if err != nil {
|
|
return g.SliceStr{}, g.SliceStr{}
|
|
}
|
|
|
|
//获取统计数据
|
|
xAxis = append(xAxis, gtime.New(monthStart).Format("Y-m"))
|
|
yAxis = append(yAxis, gconv.String(count))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (s *visitorService) getWeekStatistic(ctx context.Context, lastWeekNum int, condition g.Map) (xAxis g.SliceStr, yAxis g.SliceStr) {
|
|
for ; 1 <= lastWeekNum; lastWeekNum-- {
|
|
weekDate, startTimestamp := s.getLastWeekFirstDate(lastWeekNum)
|
|
endTimestamp := gtime.New(weekDate).AddDate(0, 0, 7).Unix()
|
|
|
|
count, err := dao.VisitorRecord.Ctx(ctx).As("vr").Where(condition).WhereBetween(dao.VisitorRecord.Columns().VisitAt, startTimestamp, endTimestamp).Count()
|
|
if err != nil {
|
|
return g.SliceStr{}, g.SliceStr{}
|
|
}
|
|
|
|
//获取第几周
|
|
_, weekNum := gtime.New(weekDate).ISOWeek()
|
|
xAxis = append(xAxis, fmt.Sprintf("第%d周", weekNum))
|
|
yAxis = append(yAxis, gconv.String(count))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
*
|
|
|
|
获取本周周一的日期
|
|
*/
|
|
func (s *visitorService) getFirstDateOfWeek() (weekMonday string, dateTimestamp int64) {
|
|
now := time.Now()
|
|
|
|
offset := int(time.Monday - now.Weekday())
|
|
if offset > 0 {
|
|
offset = -6
|
|
}
|
|
|
|
weekStartDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
|
|
weekMonday = weekStartDate.Format("2006-01-02")
|
|
dateTimestamp = gtime.New(weekMonday).Unix()
|
|
|
|
return
|
|
}
|
|
|
|
/*
|
|
*
|
|
|
|
获取本周周一的日期
|
|
*/
|
|
func (s *visitorService) getLastWeekFirstDate(weekNum int) (weekMonday string, dateTimestamp int64) {
|
|
thisWeekMonday, _ := s.getFirstDateOfWeek()
|
|
TimeMonday, _ := time.Parse("2006-01-02", thisWeekMonday)
|
|
lastWeekMonday := TimeMonday.AddDate(0, 0, -7*(weekNum-1))
|
|
weekMonday = lastWeekMonday.Format("2006-01-02")
|
|
dateTimestamp = gtime.New(weekMonday).Unix()
|
|
|
|
return
|
|
}
|
|
|