访客登记
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

303 lines
8.1 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"
"vistor/internal/model/entity"
)
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)
10 months ago
GetDiffDays(t1, t2 time.Time) int
VisitorList(ctx context.Context, req *v1.VisitorListReq) (res *v1.VisitorListRes, err error)
}
func (s *visitorService) VisitorList(ctx context.Context, req *v1.VisitorListReq) (res *v1.VisitorListRes, err error) {
condition := g.Map{}
var records []*entity.VisitorRecord
if req.PageNum == 0 {
req.PageNum = 1
}
if req.PageSize == 0 {
req.PageSize = 15
}
if req.VisitorName != "" {
condition["visitor_name like ?"] = "%" + req.VisitorName + "%"
}
if req.VisitorIdentity != "" {
condition["visitor_identity like ?"] = "%" + req.VisitorIdentity + "%"
}
if req.VisitorPhone != "" {
condition["visitor_phone like ?"] = "%" + req.VisitorPhone + "%"
}
query := dao.VisitorRecord.Ctx(ctx).Where(condition)
if req.StartDate != 0 || req.EndDate != 0 {
query = query.WhereBetween(dao.VisitorRecord.Columns().VisitAt, req.StartDate, req.EndDate)
}
total, err := query.Count()
if err != nil {
return nil, err
}
err = query.Page(req.PageNum, req.PageSize).Order("id desc").Scan(&records)
if err != nil {
return nil, err
}
res = &v1.VisitorListRes{
List: records,
Total: total,
Current: req.PageNum,
}
return
}
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 like ?"] = "%" + req.VisitorName + "%"
}
if req.VisitorIdentity != "" {
condition["vr.visitor_identity like ?"] = "%" + req.VisitorIdentity + "%"
}
if req.VisitorPhone != "" {
condition["vr.visitor_phone like ?"] = "%" + req.VisitorPhone + "%"
}
if req.StatisticType == consts.StatisticTypeDay {
10 months ago
diff := s.GetDiffDays(gtime.New(req.EndDate).Time, gtime.New(req.StartDate).Time)
duration := gconv.Int(diff) + 1
10 months ago
if duration > 30 {
return nil, gerror.Newf("请选择30天内日期进行查询")
}
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
}
10 months ago
// GetDiffDays 获取两个时间相差的天数,0表同一天,正数表t1>t2,负数表t1<t2
func (s *visitorService) GetDiffDays(t1, t2 time.Time) int {
t1 = time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.Local)
t2 = time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.Local)
return int(t1.Sub(t2).Hours() / 24)
}
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
}