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) 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 []*model.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 { diff := s.GetDiffDays(gtime.New(req.EndDate).Time, gtime.New(req.StartDate).Time) duration := gconv.Int(diff) + 1 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 } // GetDiffDays 获取两个时间相差的天数,0表同一天,正数表t1>t2,负数表t1 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 }