package dao import ( "context" "customer-server/model/dto" "customer-server/model/entity" "gitea.com/red-future/common/beans" "gitea.com/red-future/common/db/mongo" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "go.mongodb.org/mongo-driver/v2/bson" ) // dataStatistics DAO 单例 var DataStatistics = new(dataStatistics) type dataStatistics struct{} // Insert 插入数据统计 func (d *dataStatistics) Insert(ctx context.Context, data *entity.DataStatistics) (err error) { // 如果 ID 为空,生成一个新的 ObjectID if data.Id == nil || data.Id.IsZero() { newId := bson.NewObjectID() data.Id = &newId // 取地址赋值给指针类型 } // 使用 common/db/mongo.DB().Insert,自动添加 tenantId、creator、updater 等字段 // 确保查询时能通过 tenantId 正确过滤数据 _, err = mongo.DB().Insert(ctx, []interface{}{data}, entity.DataStatisticsCollection) return } // Update 更新数据统计 func (d *dataStatistics) Update(ctx context.Context, req *dto.UpdateDataStatisticsReq) (err error) { objectId, err := bson.ObjectIDFromHex(req.Id) if err != nil { return } filter := bson.M{"_id": objectId} updateFields := bson.M{} // 使用 gconv 和 gtime 转换日期 if !g.IsEmpty(req.Date) { if dateTime := gtime.NewFromStr(req.Date); dateTime != nil { updateFields["date"] = dateTime.Time } } if !g.IsEmpty(req.AccountName) { updateFields["accountName"] = req.AccountName } if !g.IsEmpty(req.CustomerServiceName) { updateFields["customerServiceName"] = req.CustomerServiceName } if !g.IsEmpty(req.CustomerServicePlatform) { updateFields["customerServicePlatform"] = req.CustomerServicePlatform } if req.InboundCount != nil { updateFields["inboundCount"] = *req.InboundCount } if req.ActiveCount != nil { updateFields["activeCount"] = *req.ActiveCount } if req.ServedCount != nil { updateFields["servedCount"] = *req.ServedCount } if req.ContactCardSentCount != nil { updateFields["contactCardSentCount"] = *req.ContactCardSentCount } if req.NameCardSentCount != nil { updateFields["nameCardSentCount"] = *req.NameCardSentCount } if req.LeftContactInfoCount != nil { updateFields["leftContactInfoCount"] = *req.LeftContactInfoCount } if req.ResponseRate30s != nil { updateFields["responseRate30s"] = *req.ResponseRate30s } if req.ResponseRate60s != nil { updateFields["responseRate60s"] = *req.ResponseRate60s } if req.ResponseRate360s != nil { updateFields["responseRate360s"] = *req.ResponseRate360s } if len(updateFields) > 0 { _, err = mongo.DB().Update(ctx, filter, bson.M{"$set": updateFields}, entity.DataStatisticsCollection) } return } // buildListFilter 构建列表查询的过滤条件 func (d *dataStatistics) buildListFilter(req *dto.ListDataStatisticsReq) bson.M { filter := bson.M{} // 客服平台筛选 if !g.IsEmpty(req.CustomerServicePlatform) { filter["customerServicePlatform"] = req.CustomerServicePlatform } // 日期范围筛选:支持单独传 StartDate 或 EndDate,或同时传两者 // 前端传入字符串格式(YYYY-MM-DD),需要转换为 time.Time 进行比较 if !g.IsEmpty(req.StartDate) || !g.IsEmpty(req.EndDate) { dateFilter := bson.M{} if !g.IsEmpty(req.StartDate) { // 使用 gtime 转换,设置为当天 00:00:00 if startTime := gtime.NewFromStr(req.StartDate); startTime != nil { dateFilter["$gte"] = startTime.Time } } if !g.IsEmpty(req.EndDate) { // 使用 gtime 转换,设置为当天 23:59:59 if endTime := gtime.NewFromStr(req.EndDate + " 23:59:59"); endTime != nil { dateFilter["$lte"] = endTime.Time } } filter["date"] = dateFilter } return filter } // checkTotalCount 检查总数 func (d *dataStatistics) checkTotalCount(ctx context.Context, filter bson.M) (total int64, err error) { total, err = mongo.DB().Count(ctx, filter, entity.DataStatisticsCollection) return } // List 获取数据统计列表 func (d *dataStatistics) List(ctx context.Context, req *dto.ListDataStatisticsReq) (list []*entity.DataStatistics, total int64, err error) { // 构建查询过滤条件 filter := d.buildListFilter(req) // 检查总数 total, err = d.checkTotalCount(ctx, filter) if err != nil { return } pageNum := req.PageNum if pageNum <= 0 { pageNum = 1 } pageSize := req.PageSize if pageSize <= 0 { pageSize = 20 } // 使用统一的mongo.DB().Find方法(支持分页和排序) page := &beans.Page{ PageNum: int64(pageNum), PageSize: int64(pageSize), } orderBy := []beans.OrderBy{ {Field: "date", Order: beans.Desc}, // 按日期倒序 } _, err = mongo.DB().Find(ctx, filter, &list, entity.DataStatisticsCollection, page, orderBy) return } // FindAllForExport 查询所有符合条件的数据统计(用于导出,不分页,需要租户过滤) func (d *dataStatistics) FindAllForExport(ctx context.Context, req *dto.ExportDataStatisticsReq) (list []*entity.DataStatistics, err error) { // 构建查询过滤条件(复用 buildListFilter 逻辑) filter := bson.M{} // 客服平台筛选 if !g.IsEmpty(req.CustomerServicePlatform) { filter["customerServicePlatform"] = req.CustomerServicePlatform } // 日期范围筛选 if !g.IsEmpty(req.StartDate) || !g.IsEmpty(req.EndDate) { dateFilter := bson.M{} if !g.IsEmpty(req.StartDate) { if startTime := gtime.NewFromStr(req.StartDate); startTime != nil { dateFilter["$gte"] = startTime.Time } } if !g.IsEmpty(req.EndDate) { if endTime := gtime.NewFromStr(req.EndDate + " 23:59:59"); endTime != nil { dateFilter["$lte"] = endTime.Time } } filter["date"] = dateFilter } // 使用 mongo.DB().Find 查询,自动添加 tenantId 过滤,确保租户数据隔离 // 不分页,设置一个足够大的PageSize page := &beans.Page{ PageNum: 1, PageSize: 100000, // 导出场景:设置足够大的PageSize } orderBy := []beans.OrderBy{ {Field: "date", Order: beans.Desc}, // 按日期倒序 } _, err = mongo.DB().Find(ctx, filter, &list, entity.DataStatisticsCollection, page, orderBy) return list, err }