访客登记
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.
visitor/internal/service/visitor.go

241 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.SubTypeLast4Week:
weekNum = 4
case consts.SubTypeLast8Week:
weekNum = 8
case consts.SubTypeLast12Week:
weekNum = 12
}
//获取按周统计数据
xAxis, yAxis = s.getWeekStatistic(ctx, weekNum, condition)
} else if req.StatisticType == consts.StatisticTypeMonth {
switch req.SubType {
case consts.SubTypeLast4Month:
monthNum = 4
case consts.SubTypeLast8Month:
monthNum = 8
case consts.SubTypeLast12Month:
monthNum = 12
}
//获取按月统计数据
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
}