package service import ( "electricity_bill_calc/exceptions" "electricity_bill_calc/logger" "electricity_bill_calc/model" "electricity_bill_calc/repository" "electricity_bill_calc/types" "electricity_bill_calc/vo" "github.com/doug-martin/goqu/v9" _ "github.com/doug-martin/goqu/v9/dialect/postgres" "github.com/jinzhu/copier" "github.com/samber/lo" "go.uber.org/zap" ) type _ReportService struct { log *zap.Logger ds goqu.DialectWrapper } var ReportService = _ReportService{ log: logger.Named("Service", "Report"), ds: goqu.Dialect("postgres"), } // 将指定报表列入计算任务 func (rs _ReportService) DispatchReportCalculate(rid string) error { rs.log.Info("将指定报表列入计算任务", zap.String("Report", rid)) _, err := repository.CalculateRepository.UpdateReportTaskStatus(rid, model.REPORT_CALCULATE_TASK_STATUS_PENDING, nil) if err != nil { rs.log.Error("未能将指定报表列入计算任务", zap.Error(err)) return err } return nil } // 列出指定用户下的所有尚未发布的报表索引 func (rs _ReportService) ListDraftReportIndicies(uid string) ([]*vo.ReportIndexQueryResponse, error) { rs.log.Info("列出指定用户下的所有尚未发布的报表", zap.String("User", uid)) indicies, err := repository.ReportRepository.ListDraftReportIndicies(uid) if err != nil { rs.log.Error("未能获取指定用户下所有未发布报表的索引", zap.Error(err)) return make([]*vo.ReportIndexQueryResponse, 0), err } parkIds := lo.Map(indicies, func(elem *model.ReportIndex, _ int) string { return elem.Park }) parks, err := repository.ParkRepository.RetrieveParks(parkIds) if err != nil { rs.log.Error("未能获取到相应报表对应的园区详细信息", zap.Error(err)) return make([]*vo.ReportIndexQueryResponse, 0), err } assembled := lo.Reduce(indicies, func(acc []*vo.ReportIndexQueryResponse, elem *model.ReportIndex, _ int) []*vo.ReportIndexQueryResponse { park, _ := lo.Find(parks, func(park *model.Park) bool { return park.Id == elem.Park }) var ( simplifiedPark vo.SimplifiedParkDetail simplifiedReport vo.SimplifiedReportIndex ) copier.Copy(&simplifiedPark, park) copier.Copy(&simplifiedReport, elem) acc = append(acc, &vo.ReportIndexQueryResponse{ Park: simplifiedPark, Report: lo.ToPtr(simplifiedReport), }) return acc }, make([]*vo.ReportIndexQueryResponse, 0)) return assembled, nil } // 获取指定报表中的包含索引、园区以及用户信息的详细信息 func (rs _ReportService) RetrieveReportIndexDetail(rid string) (*model.UserDetail, *model.Park, *model.ReportIndex, error) { index, err := repository.ReportRepository.GetReportIndex(rid) if err != nil { rs.log.Error("未能获取到指定报表的索引", zap.Error(err)) return nil, nil, nil, exceptions.NewNotFoundErrorFromError("未能获取到指定报表的索引", err) } park, err := repository.ParkRepository.RetrieveParkDetail(index.Park) if err != nil { rs.log.Error("未能获取到指定报表对应的园区详细信息", zap.Error(err)) return nil, nil, nil, exceptions.NewNotFoundErrorFromError("未能获取到指定报表对应的园区详细信息", err) } user, err := repository.UserRepository.FindUserDetailById(park.UserId) if err != nil { rs.log.Error("未能获取到指定报表对应的用户详细信息", zap.Error(err)) return nil, nil, nil, exceptions.NewNotFoundErrorFromError("未能获取到指定报表对应的用户详细信息", err) } return user, park, index, nil } // 根据给定的园区ID列表,查询园区以及用户的详细信息 func (rs _ReportService) queryParkAndUserDetails(pids []string) ([]*model.Park, []*model.UserDetail, error) { parks, err := repository.ParkRepository.RetrieveParks(pids) if err != nil { rs.log.Error("未能获取到相应报表对应的园区详细信息", zap.Error(err)) return make([]*model.Park, 0), make([]*model.UserDetail, 0), exceptions.NewNotFoundErrorFromError("未能获取到相应报表对应的园区详细信息", err) } userIds := lo.Map(parks, func(elem *model.Park, _ int) string { return elem.UserId }) users, err := repository.UserRepository.RetrieveUsersDetail(userIds) if err != nil { rs.log.Error("未能获取到相应报表对应的用户详细信息", zap.Error(err)) return make([]*model.Park, 0), make([]*model.UserDetail, 0), exceptions.NewNotFoundErrorFromError("未能获取到相应报表对应的用户详细信息", err) } return parks, users, nil } // 查询指定的核算报表列表 func (rs _ReportService) QueryReports(uid, pid *string, page uint, keyword *string, periodBegin, periodEnd *types.Date) ([]*vo.ComprehensiveReportQueryResponse, int64, error) { rs.log.Info("查询指定的核算报表列表", zap.Stringp("User", uid), zap.Stringp("Park", pid), zap.Uint("Page", page), zap.Stringp("Keyword", keyword), logger.DateFieldp("PeriodBegin", periodBegin), logger.DateFieldp("PeriodEnd", periodEnd)) reports, total, err := repository.ReportRepository.ComprehensiveReportSearch(uid, pid, page, keyword, periodBegin, periodEnd) if err != nil { rs.log.Error("未能查询到指定的核算报表列表", zap.Error(err)) return make([]*vo.ComprehensiveReportQueryResponse, 0), 0, err } parkIds := lo.Map(reports, func(elem *model.ReportIndex, _ int) string { return elem.Park }) parks, users, err := rs.queryParkAndUserDetails(parkIds) if err != nil { return make([]*vo.ComprehensiveReportQueryResponse, 0), 0, err } assembled := lo.Reduce( reports, func(acc []*vo.ComprehensiveReportQueryResponse, elem *model.ReportIndex, _ int) []*vo.ComprehensiveReportQueryResponse { park, _ := lo.Find(parks, func(park *model.Park) bool { return park.Id == elem.Park }) user, _ := lo.Find(users, func(user *model.UserDetail) bool { return user.Id == park.UserId }) var ( simplifiedUser vo.SimplifiedUserDetail simplifiedPark vo.SimplifiedParkDetail simplifiedReport vo.SimplifiedReportIndex ) copier.Copy(&simplifiedUser, user) copier.Copy(&simplifiedPark, park) copier.Copy(&simplifiedReport, elem) acc = append(acc, &vo.ComprehensiveReportQueryResponse{ User: simplifiedUser, Park: simplifiedPark, Report: simplifiedReport, }) return acc }, make([]*vo.ComprehensiveReportQueryResponse, 0), ) return assembled, total, nil } // 查询当前待审核的核算报表撤回申请列表 func (rs _ReportService) ListWithdrawalRequests(page uint, keyword *string) ([]*vo.ComprehensiveReportQueryResponse, int64, error) { rs.log.Info("查询当前待审核的核算报表撤回申请列表", zap.Uint("Page", page), zap.Stringp("Keyword", keyword)) reports, total, err := repository.ReportRepository.ListWithdrawAppliedReports(page, keyword) if err != nil { rs.log.Error("未能查询到当前待审核的核算报表撤回申请列表", zap.Error(err)) return make([]*vo.ComprehensiveReportQueryResponse, 0), 0, err } parkIds := lo.Map(reports, func(elem *model.ReportIndex, _ int) string { return elem.Park }) parks, users, err := rs.queryParkAndUserDetails(parkIds) if err != nil { return make([]*vo.ComprehensiveReportQueryResponse, 0), 0, err } assembled := lo.Reduce( reports, func(acc []*vo.ComprehensiveReportQueryResponse, elem *model.ReportIndex, _ int) []*vo.ComprehensiveReportQueryResponse { park, _ := lo.Find(parks, func(park *model.Park) bool { return park.Id == elem.Park }) user, _ := lo.Find(users, func(user *model.UserDetail) bool { return user.Id == park.UserId }) var ( simplifiedUser vo.SimplifiedUserDetail simplifiedPark vo.SimplifiedParkDetail simplifiedReport vo.SimplifiedReportIndex ) copier.Copy(&simplifiedUser, user) copier.Copy(&simplifiedPark, park) copier.Copy(&simplifiedReport, elem) acc = append(acc, &vo.ComprehensiveReportQueryResponse{ User: simplifiedUser, Park: simplifiedPark, Report: simplifiedReport, }) return acc }, make([]*vo.ComprehensiveReportQueryResponse, 0), ) return assembled, total, nil }