diff --git a/service/report.go b/service/report.go index e5603a0..d0b1ab1 100644 --- a/service/report.go +++ b/service/report.go @@ -1,10 +1,12 @@ package service import ( + "database/sql" "electricity_bill_calc/cache" "electricity_bill_calc/config" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" + "electricity_bill_calc/logger" "electricity_bill_calc/model" "electricity_bill_calc/tools" "fmt" @@ -15,56 +17,73 @@ import ( "github.com/google/uuid" "github.com/samber/lo" "github.com/shopspring/decimal" - "xorm.io/builder" + "github.com/uptrace/bun" + "go.uber.org/zap" ) -type _ReportService struct{} +type _ReportService struct { + l *zap.Logger +} -var ReportService _ReportService +var ReportService = _ReportService{ + l: logger.Named("Service", "Report"), +} func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewestReport, error) { if cachedParks, _ := cache.RetreiveSearch[[]model.ParkNewestReport]("park_newest_report", uid); cachedParks != nil { return *cachedParks, nil } - parks := make([]model.ParkNewestReport, 0) - err := global.DBConn. - Alias("p"). - Join("LEFT", []string{"report", "r"}, "r.park_id=p.id"). - Where(builder.Eq{"p.user_id": uid, "p.enabled": true}). - Find(&parks) + + ctx, cancel := global.TimeoutContext() + defer cancel() + reports := make([]model.Report, 0) + err := global.DB.NewSelect().Model(&reports).Relation("Park"). + Where("p.user_id = ?", uid). + Where("p.enabled = ?", true). + Scan(ctx) if err != nil { return make([]model.ParkNewestReport, 0), err } + reducedParks := lo.Reduce( - parks, - func(acc map[string]model.ParkNewestReport, elem model.ParkNewestReport, index int) map[string]model.ParkNewestReport { + reports, + func(acc map[string]model.ParkNewestReport, elem model.Report, index int) map[string]model.ParkNewestReport { if v, ok := acc[elem.Park.Id]; ok { - if elem.Report != nil { - if v.Report == nil || (elem.Report.Period.After(v.Report.Period)) { - acc[elem.Park.Id] = elem + if v.Report == nil || (elem.Period.After(v.Report.Period)) { + acc[elem.Park.Id] = model.ParkNewestReport{ + Report: &elem, + Park: *elem.Park, } } } else { - acc[elem.Park.Id] = elem + acc[elem.Park.Id] = model.ParkNewestReport{ + Report: &elem, + Park: *elem.Park, + } } return acc }, make(map[string]model.ParkNewestReport, 0), ) - cache.CacheSearch(reducedParks, []string{"park", "report"}, "park_newest_report", uid) + relations := lo.Map(reports, func(r model.Report, _ int) string { + return fmt.Sprint("report:%s", r.Id) + }) + relations = append(relations, "park", "report") + cache.CacheSearch(reducedParks, relations, "park_newest_report", uid) return lo.Values(reducedParks), nil } func (_ReportService) IsNewPeriodValid(uid, pid string, period time.Time) (bool, error) { + ctx, cancel := global.TimeoutContext() + defer cancel() reports := make([]model.Report, 0) if cachedReport, _ := cache.RetreiveSearch[[]model.Report]("report", "user", uid, "park", pid); cachedReport != nil { reports = *cachedReport } else { - err := global.DBConn. - Table("report").Alias("r"). - Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). - Where(builder.Eq{"p.user_id": uid, "r.park_id": pid}). - Find(&reports) + err := global.DB.NewSelect().Model(&reports).Relation("Park"). + Where("p.user_id = ?", uid). + Where("r.park_id = ?", pid). + Scan(ctx) if err != nil { return false, nil } @@ -122,12 +141,15 @@ func (_ReportService) IsNewPeriodValid(uid, pid string, period time.Time) (bool, } func (_ReportService) InitializeNewReport(parkId string, period time.Time) (string, error) { + ctx, cancel := global.TimeoutContext() + defer cancel() + periods := make([]model.Report, 0) - err := global.DBConn. - Table("report"). - Where(builder.Eq{"park_id": parkId, "published": true}). - Asc("period"). - Find(&periods) + err := global.DB.NewSelect().Model(&periods). + Where("park_id = ?", parkId). + Where("published = ?", true). + Order("period asc"). + Scan(ctx) if err != nil { return "", err } @@ -146,7 +168,9 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri if maxPublishedReport != nil { // 获取上一期的所有户表信息,并获取当前已启用的所有用户 lastPeriodCustomers := make([]model.EndUserDetail, 0) - err = global.DBConn.Where(builder.Eq{"report_id": maxPublishedReport.Id}).Find(&lastPeriodCustomers) + err = global.DB.NewSelect().Model(&lastPeriodCustomers). + Where("report_id = ?", maxPublishedReport.Id). + Scan(ctx) if err != nil { return "", err } @@ -162,21 +186,25 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri indexedLastPeriodCustomers = make(map[string]model.EndUserDetail, 0) } currentActivatedCustomers := make([]model.Meter04KV, 0) - err = global.DBConn.Where(builder.Eq{"park_id": parkId, "enabled": true}).Find(¤tActivatedCustomers) + err = global.DB.NewSelect().Model(¤tActivatedCustomers). + Where("park_id = ?", parkId). + Where("enabled = ?", true). + Scan(ctx) if err != nil { return "", err } var parkInfo = new(model.Park) - has, err := global.DBConn.ID(parkId).NoAutoCondition().Get(parkInfo) - if err != nil || !has { + err = global.DB.NewSelect().Model(parkInfo). + Where("id = ?", parkId). + Scan(ctx) + if err != nil || parkInfo == nil { return "", exceptions.NewNotFoundError(fmt.Sprintf("指定园区未找到, %v", err)) } // 生成新一期的报表 - tx := global.DBConn.NewSession() - if err = tx.Begin(); err != nil { + tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) + if err != nil { return "", err } - defer tx.Close() // 插入已经生成的报表索引信息和园区概况信息 newReport := model.Report{ Id: uuid.New().String(), @@ -191,7 +219,12 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri newReportSummary := model.ReportSummary{ ReportId: newReport.Id, } - _, err = tx.Insert(newReport, newReportSummary) + _, err = tx.NewInsert().Model(&newReport).Exec(ctx) + if err != nil { + tx.Rollback() + return "", err + } + _, err = tx.NewInsert().Model(&newReportSummary).Exec(ctx) if err != nil { tx.Rollback() return "", err @@ -223,7 +256,7 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri newEndUser.LastPeriodFlat = lastPeriod.CurrentPeriodFlat newEndUser.LastPeriodValley = lastPeriod.CurrentPeriodValley } - _, err = tx.Insert(newEndUser) + _, err = tx.NewInsert().Model(&newEndUser).Exec(ctx) if err != nil { tx.Rollback() return "", err @@ -242,14 +275,18 @@ func (_ReportService) RetreiveReportIndex(rid string) (*model.Report, error) { if cachedReport, _ := cache.RetreiveEntity[model.Report]("report", rid); cachedReport != nil { return cachedReport, nil } - reports := make([]model.Report, 0) - err := global.DBConn.Where(builder.Eq{"id": rid}).Find(&reports) + ctx, cancel := global.TimeoutContext() + defer cancel() + report := new(model.Report) + err := global.DB.NewSelect().Model(report). + Where("id = ?", rid). + Scan(ctx) if err != nil { return nil, err } - if len(reports) > 0 { - cache.CacheEntity(reports[0], []string{fmt.Sprintf("report_%s", rid), "park"}, "report", rid) - return &reports[0], nil + if report != nil { + cache.CacheEntity(report, []string{fmt.Sprintf("report:%s", rid), "park"}, "report", rid) + return report, nil } else { return nil, nil } @@ -259,53 +296,63 @@ func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, e if cachedSummary, _ := cache.RetreiveEntity[model.ReportSummary]("report_summary", rid); cachedSummary != nil { return cachedSummary, nil } + + ctx, cancel := global.TimeoutContext() + defer cancel() var summary = new(model.ReportSummary) - _, err := global.DBConn.ID(rid).NoAutoCondition().Get(summary) + err := global.DB.NewSelect().Model(summary). + Where("report_id = ?", rid). + Scan(ctx) if err != nil { return nil, err } - cache.CacheEntity(summary, []string{fmt.Sprintf("report_%s", rid), "park"}, "report_summary", rid) + cache.CacheEntity(summary, []string{fmt.Sprintf("report:%s", rid), "park"}, "report_summary", rid) return summary, nil } func (_ReportService) UpdateReportSummary(summary *model.ReportSummary) error { - _, err := global.DBConn.ID(summary.ReportId).Cols("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee").Update(summary) + ctx, cancel := global.TimeoutContext() + defer cancel() + _, err := global.DB.NewUpdate().Model(summary). + WherePK(). + Column("overall", "overall_fee", "critical", "critical_fee", "peak", "peak_fee", "valley", "valley_fee", "basic_fee", "adjust_fee"). + Exec(ctx) if err == nil { - cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId)) + cache.AbolishRelation(fmt.Sprintf("report:%s", summary.ReportId)) } return err } func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error { + ctx, cancel := global.TimeoutContext() + defer cancel() var report = new(model.Report) - has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(report) + err := global.DB.NewSelect().Model(report).Relation("Summary"). + Where("r.id = ?", reportId). + Scan(ctx) + if err != nil || report == nil { + return exceptions.NewNotFoundErrorFromError("未找到指定报表", err) + } + + tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return err } - if !has { - return exceptions.NewNotFoundError("未找到指定报表") - } - var summary = new(model.ReportSummary) - has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary) - if err != nil { - return err - } - if !has { - return exceptions.NewNotFoundError("未找到指定报表的园区概况") - } - tx := global.DBConn.NewSession() - if err = tx.Begin(); err != nil { - return err - } - defer tx.Close() - summary.CalculatePrices() - _, err = tx.ID(summary.ReportId).Cols("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price", "consumption_fee").Update(summary) + + report.Summary.CalculatePrices() + _, err = tx.NewUpdate().Model(report.Summary). + WherePK(). + Column("overall_price", "critical_price", "peak_price", "flat", "flat_fee", "flat_price", "valley_price", "consumption_fee"). + Exec(ctx) if err != nil { tx.Rollback() return err } report.StepState.Summary = true - _, err = tx.ID(report.Id).Cols("step_state").Update(report) + _, err = tx.NewUpdate().Model(report). + WherePK(). + Column("step_state"). + Exec(ctx) if err != nil { tx.Rollback() return err @@ -315,7 +362,7 @@ func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error { tx.Rollback() return err } - cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId)) + cache.AbolishRelation(fmt.Sprintf("report:%s", reportId)) return nil } @@ -323,37 +370,54 @@ func (_ReportService) FetchWillDulutedMaintenanceFees(reportId string) ([]model. if cachedFees, _ := cache.RetreiveSearch[[]model.WillDilutedFee]("will_diluted_fee", "report", reportId); cachedFees != nil { return *cachedFees, nil } + ctx, cancel := global.TimeoutContext() + defer cancel() + fees := make([]model.WillDilutedFee, 0) - err := global.DBConn.Where(builder.Eq{"report_id": reportId}).Asc("created_at").Find(&fees) + err := global.DB.NewSelect().Model(&fees). + Where("report_id = ?", reportId). + Order("created_at asc"). + Scan(ctx) if err != nil { return make([]model.WillDilutedFee, 0), nil } - cache.CacheSearch(fees, []string{"will_diluted_fee", fmt.Sprintf("report_%s", reportId), "park"}, "will_diluted_fee", "report", reportId) + relations := lo.Map(fees, func(f model.WillDilutedFee, _ int) string { + return fmt.Sprintf("will_diluted_fee:%s", f.Id) + }) + relations = append(relations, fmt.Sprintf("report:will_diluted_fee:%s", reportId), fmt.Sprintf("report:%s", reportId), "park") + cache.CacheSearch(fees, relations, "will_diluted_fee", "report", reportId) return fees, nil } func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error { + ctx, cancel := global.TimeoutContext() + defer cancel() + fee.Id = utils.UUIDString() - _, err := global.DBConn.Insert(fee) - cache.AbolishRelation("will_diluted_fee") + _, err := global.DB.NewInsert().Model(&fee).Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", fee.ReportId)) return err } func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.WillDilutedFee) error { - tx := global.DBConn.NewSession() - if err := tx.Begin(); err != nil { + ctx, cancel := global.TimeoutContext() + defer cancel() + + tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) + if err != nil { return err } - defer tx.Close() // 首先删除所有预定义的部分,条件是指定报表ID,SourceID不为空。 - cond := builder.Eq{"report_id": reportId}.And(builder.NotNull{"source_id"}) - _, err := tx.Table(new(model.WillDilutedFee)).Where(cond).Delete() + _, err = tx.NewDelete().Model((*model.WillDilutedFee)(nil)). + Where("report_id = ?", reportId). + Where("source_id is not null"). + Exec(ctx) if err != nil { tx.Rollback() return err } // 然后插入新的记录 - _, err = tx.Insert(fees) + _, err = tx.NewInsert().Model(&fees).Exec(ctx) if err != nil { return err } @@ -362,40 +426,65 @@ func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.Will tx.Rollback() return err } - cache.AbolishRelation("will_diluted_fee") + cache.AbolishRelation(fmt.Sprintf("report:will_diluted_fee:%s", reportId)) return nil } func (_ReportService) UpdateMaintenanceFee(feeId string, updates map[string]interface{}) (err error) { - _, err = global.DBConn.Table(new(model.WillDilutedFee)).ID(feeId).Update(updates) - cache.AbolishRelation("will_diluted_fee") + ctx, cancel := global.TimeoutContext() + defer cancel() + + _, err = global.DB.NewUpdate().Model(updates).TableExpr("will_diluted_fee"). + Where("id = ?", feeId). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", feeId)) return } func (_ReportService) DeleteWillDilutedFee(fee string) (err error) { - _, err = global.DBConn.ID(fee).NoAutoCondition().Delete(new(model.WillDilutedFee)) - cache.AbolishRelation("will_diluted_fee") + ctx, cancel := global.TimeoutContext() + defer cancel() + + _, err = global.DB.NewDelete().Model((*model.WillDilutedFee)(nil)). + Where("id = ?", fee). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("will_diluted_fee:%s", fee)) return } func (_ReportService) ProgressReportWillDilutedFee(report model.Report) (err error) { + ctx, cancel := global.TimeoutContext() + defer cancel() + report.StepState.WillDiluted = true - _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) - cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) + _, err = global.DB.NewUpdate().Model(&report). + Column("step_state"). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) ProgressReportRegisterEndUser(report model.Report) (err error) { + ctx, cancel := global.TimeoutContext() + defer cancel() + report.StepState.Submeter = true - _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) - cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) + _, err = global.DB.NewUpdate().Model(&report). + Column("step_state"). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) ProgressReportCalculate(report model.Report) (err error) { + ctx, cancel := global.TimeoutContext() + defer cancel() + report.StepState.Calculate = true - _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) - cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) + _, err = global.DB.NewUpdate().Model(&report). + Column("step_state"). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } @@ -403,96 +492,102 @@ func (_ReportService) RetreiveParkEndUserMeterType(reportId string) (int, error) if cachedType, _ := cache.RetreiveEntity[int]("park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)); cachedType != nil { return *cachedType, nil } - var types = make([]int, 0) - err := global.DBConn. - Table("park").Alias("p"). - Join("INNER", []string{"report", "r"}, "r.park_id=p.id"). - Where(builder.Eq{"r.id": reportId}). - Select("p.meter_04kv_type"). - Find(&types) + ctx, cancel := global.TimeoutContext() + defer cancel() + + var mType int + err := global.DB.NewSelect().Model((*model.Report)(nil)).Relation("Park"). + Where("r.id = ?", reportId). + Scan(ctx, &mType) if err != nil { return -1, err } - if len(types) == 0 { - return -1, nil - } - cache.CacheEntity(types[0], []string{fmt.Sprintf("report_%s", reportId), "park"}, "park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)) - return types[0], nil + cache.CacheEntity(mType, []string{fmt.Sprintf("report:%s", reportId), "park"}, "park_end_user_meter_type", fmt.Sprintf("report_%s", reportId)) + return mType, nil } func (_ReportService) PublishReport(report model.Report) (err error) { + ctx, cancel := global.TimeoutContext() + defer cancel() + report.Published = true report.PublishedAt = lo.ToPtr(time.Now()) report.StepState.Publish = true - _, err = global.DBConn.ID(report.Id).Cols("step_state", "published", "published_at").Update(report) - cache.AbolishRelation("report") - cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) + _, err = global.DB.NewUpdate().Model(&report). + WherePK(). + Column("step_state", "published", "published_at"). + Exec(ctx) + cache.AbolishRelation(fmt.Sprintf("report:%s", report.Id)) return } func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword string, requestPeriod *time.Time, requestPage int, onlyPublished bool) ([]model.JoinedReportForWithdraw, int64, error) { - var conditions = make([]string, 0) + var ( + conditions = make([]string, 0) + reports = make([]model.Report, 0) + cond = global.DB.NewSelect(). + Model(&reports). + Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Relation("Enterprise") + }) + ) conditions = append(conditions, strconv.Itoa(requestPage)) - cond := builder.NewCond() if onlyPublished { - cond = cond.And(builder.Eq{"r.published": true}) + cond = cond.Where("r.published = ?", true) } conditions = append(conditions, strconv.FormatBool(onlyPublished)) if len(requestUser) > 0 { - cond = cond.And(builder.Eq{"u.id": requestUser}) + cond = cond.Where("p.user_id = ?", requestUser) conditions = append(conditions, requestUser) } if len(requestPark) > 0 { - cond = cond.And(builder.Eq{"p.id": requestPark}) + cond = cond.Where("p.id = ?", requestPark) conditions = append(conditions, requestPark) } if requestPeriod != nil { - cond = cond.And(builder.Eq{"r.period": *requestPeriod}) + cond = cond.Where("r.period = ?", *requestPeriod) conditions = append(conditions, strconv.FormatInt(requestPeriod.Unix(), 10)) } if len(requestKeyword) > 0 { - cond = cond.And( - builder.Like{"u.name", requestKeyword}. - Or(builder.Like{"p.name", requestKeyword}). - Or(builder.Like{"u.abbr", requestKeyword}). - Or(builder.Like{"p.abbr", requestKeyword}). - Or(builder.Like{"u.address", requestKeyword}). - Or(builder.Like{"p.address", requestKeyword}), - ) + keywordCond := "%" + requestKeyword + "%" + cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Where("p.name like ?", keywordCond). + WhereOr("d.name like ?", keywordCond). + WhereOr("d.abbr like ?", keywordCond). + WhereOr("p.abbr like ?", keywordCond). + WhereOr("d.address like ?", keywordCond). + WhereOr("p.address like ?", keywordCond) + }) conditions = append(conditions, requestKeyword) } - var ( - total int64 - err error - ) if cachedTotal, err := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 && err == nil { - total = cachedTotal - } else { - total, err := global.DBConn. - Table("report").Alias("r"). - Join("INNER", []string{"park", "p"}, "p.id=r.park_id"). - Join("INNER", []string{"user_detail", "u"}, "u.id=p.user_id"). - Where(cond). - Count() - if err != nil { - return make([]model.JoinedReportForWithdraw, 0), -1, err + if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil { + return *cachedRecords, cachedTotal, nil } - cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...) } + ctx, cancel := global.TimeoutContext() + defer cancel() + startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize - if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil { - return *cachedRecords, total, nil - } + + total, err := cond.Limit(config.ServiceSettings.ItemsPageSize). + Offset(startItem). + ScanAndCount(ctx) + records := make([]model.JoinedReportForWithdraw, 0) - err = global.DBConn. - Table("report").Alias("r"). - Join("INNER", []string{"park", "p"}, "p.id=r.park_id"). - Join("INNER", []string{"user_detail", "u"}, "u.id=p.user_id"). - Where(cond). - Limit(config.ServiceSettings.ItemsPageSize, startItem). - Find(&records) - cache.CacheSearch(records, []string{"report", "park"}, "join_report_for_withdraw", conditions...) - return records, total, err + relations := []string{"report", "park"} + for _, r := range reports { + records = append(records, model.JoinedReportForWithdraw{ + Report: r, + Park: model.FromPark(*r.Park), + User: model.FromUserDetail(*r.Park.Enterprise), + }) + relations = append(relations, fmt.Sprintf("report:%s", r.Id)) + } + + cache.CacheCount(relations, "join_report_for_withdraw", int64(total), conditions...) + cache.CacheSearch(records, relations, "join_report_for_withdraw", conditions...) + return records, int64(total), err } func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity, error) { @@ -500,101 +595,87 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity return cachedPublicity, nil } // 资料准备 - var reportIndex = new(model.Report) - has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(reportIndex) - if err != nil || !has { + ctx, cancel := global.TimeoutContext() + defer cancel() + + var report = new(model.Report) + err := global.DB.NewSelect().Model(report). + Relation("Summary").Relation("WillDilutedFees").Relation("EndUsers"). + Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Relation("Enterprise") + }). + Where("id = ?", reportId). + Scan(ctx) + if err != nil || report == nil { return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表", err) } - var summary = new(model.ReportSummary) - has, err = global.DBConn.ID(reportId).NoAutoCondition().Get(summary) - if err != nil || !has { - return nil, exceptions.NewNotFoundErrorFromError("未找到指定的公示报表概览", err) - } - var maintenanceFeeRecords = make([]model.WillDilutedFee, 0) - err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&maintenanceFeeRecords) - if err != nil { - return nil, exceptions.NewNotFoundErrorFromError("未能获取到公示报表对应的待摊薄费用信息", err) - } - var endUserDetails = make([]model.EndUserDetail, 0) - err = global.DBConn.Where(builder.Eq{"report_id": reportId}).Find(&endUserDetails) - if err != nil { - return nil, exceptions.NewNotFoundErrorFromError("未获取到公示报表对应的终端用户抄表信息", err) - } - parkDetail, err := ParkService.FetchParkDetail(reportIndex.ParkId) - if err != nil { - return nil, exceptions.NewNotFoundErrorFromError("未找到公示报表对应的园区信息", err) - } - userDetail, err := UserService.retreiveUserDetail(parkDetail.UserId) - if err != nil { - return nil, exceptions.NewNotFoundErrorFromError("未找到公示报表对应的企业信息", err) - } // 组合数据 paidPart := model.PaidPart{ - Overall: summary.Overall, - OverallPrice: summary.OverallPrice.Decimal, - ConsumptionFee: summary.ConsumptionFee.Decimal, - OverallFee: summary.OverallFee, - Critical: decimal.NewNullDecimal(summary.Critical), - CriticalPrice: summary.CriticalPrice, - CriticalFee: decimal.NewNullDecimal(summary.CriticalFee), - Peak: decimal.NewNullDecimal(summary.Peak), - PeakPrice: summary.PeakPrice, - PeakFee: decimal.NewNullDecimal(summary.PeakFee), - Flat: decimal.NewNullDecimal(summary.Flat), - FlatPrice: summary.FlatPrice, - FlatFee: decimal.NewNullDecimal(summary.FlatFee), - Valley: decimal.NewNullDecimal(summary.Valley), - ValleyPrice: summary.ValleyPrice, - ValleyFee: decimal.NewNullDecimal(summary.ValleyFee), - BasicFee: summary.BasicFee, - AdjustFee: summary.AdjustFee, + Overall: report.Summary.Overall, + OverallPrice: report.Summary.OverallPrice.Decimal, + ConsumptionFee: report.Summary.ConsumptionFee.Decimal, + OverallFee: report.Summary.OverallFee, + Critical: decimal.NewNullDecimal(report.Summary.Critical), + CriticalPrice: report.Summary.CriticalPrice, + CriticalFee: decimal.NewNullDecimal(report.Summary.CriticalFee), + Peak: decimal.NewNullDecimal(report.Summary.Peak), + PeakPrice: report.Summary.PeakPrice, + PeakFee: decimal.NewNullDecimal(report.Summary.PeakFee), + Flat: decimal.NewNullDecimal(report.Summary.Flat), + FlatPrice: report.Summary.FlatPrice, + FlatFee: decimal.NewNullDecimal(report.Summary.FlatFee), + Valley: decimal.NewNullDecimal(report.Summary.Valley), + ValleyPrice: report.Summary.ValleyPrice, + ValleyFee: decimal.NewNullDecimal(report.Summary.ValleyFee), + BasicFee: report.Summary.BasicFee, + AdjustFee: report.Summary.AdjustFee, } endUserSummary := model.EndUserOverallPart{ - Overall: summary.CustomerConsumption.Decimal, - OverallPrice: summary.OverallPrice.Decimal, - OverallFee: summary.CustomerConsumptionFee.Decimal, - Critical: summary.CustomerConsumptionCritical, - CriticalPrice: summary.CriticalPrice, - CriticalFee: summary.CustomerConsumptionCriticalFee, - Peak: summary.CustomerConsumptionPeak, - PeakPrice: summary.PeakPrice, - PeakFee: summary.CustomerConsumptionPeakFee, - Flat: summary.CustomerConsumptionFlat, - FlatPrice: summary.FlatPrice, - FlatFee: summary.CustomerConsumptionFlatFee, - Valley: summary.CustomerConsumptionValley, - ValleyPrice: summary.ValleyPrice, - ValleyFee: summary.CustomerConsumptionValleyFee, + Overall: report.Summary.CustomerConsumption.Decimal, + OverallPrice: report.Summary.OverallPrice.Decimal, + OverallFee: report.Summary.CustomerConsumptionFee.Decimal, + Critical: report.Summary.CustomerConsumptionCritical, + CriticalPrice: report.Summary.CriticalPrice, + CriticalFee: report.Summary.CustomerConsumptionCriticalFee, + Peak: report.Summary.CustomerConsumptionPeak, + PeakPrice: report.Summary.PeakPrice, + PeakFee: report.Summary.CustomerConsumptionPeakFee, + Flat: report.Summary.CustomerConsumptionFlat, + FlatPrice: report.Summary.FlatPrice, + FlatFee: report.Summary.CustomerConsumptionFlatFee, + Valley: report.Summary.CustomerConsumptionValley, + ValleyPrice: report.Summary.ValleyPrice, + ValleyFee: report.Summary.CustomerConsumptionValleyFee, } lossPart := model.LossPart{ - Quantity: summary.Loss.Decimal, - Price: summary.OverallPrice.Decimal, - ConsumptionFee: summary.LossFee.Decimal, - Proportion: summary.LossProportion.Decimal, + Quantity: report.Summary.Loss.Decimal, + Price: report.Summary.OverallPrice.Decimal, + ConsumptionFee: report.Summary.LossFee.Decimal, + Proportion: report.Summary.LossProportion.Decimal, } publicSummary := model.PublicConsumptionOverallPart{ - Overall: summary.PublicConsumption.Decimal, - OverallPrice: summary.OverallPrice.Decimal, - ConsumptionFee: summary.PublicConsumptionFee.Decimal, - OverallFee: summary.PublicConsumptionFee.Decimal, - Critical: summary.PublicConsumptionCritical, - CriticalPrice: summary.CriticalPrice, - CriticalFee: summary.PublicConsumptionCriticalFee, - Peak: summary.PublicConsumptionPeak, - PeakPrice: summary.PeakPrice, - PeakFee: summary.PublicConsumptionPeakFee, - Flat: summary.PublicConsumptionFlat, - FlatPrice: summary.FlatPrice, - FlatFee: summary.PublicConsumptionFlatFee, - Valley: summary.PublicConsumptionValley, - ValleyPrice: summary.ValleyPrice, - ValleyFee: summary.PublicConsumptionValleyFee, - Proportion: summary.PublicConsumptionProportion.Decimal, + Overall: report.Summary.PublicConsumption.Decimal, + OverallPrice: report.Summary.OverallPrice.Decimal, + ConsumptionFee: report.Summary.PublicConsumptionFee.Decimal, + OverallFee: report.Summary.PublicConsumptionFee.Decimal, + Critical: report.Summary.PublicConsumptionCritical, + CriticalPrice: report.Summary.CriticalPrice, + CriticalFee: report.Summary.PublicConsumptionCriticalFee, + Peak: report.Summary.PublicConsumptionPeak, + PeakPrice: report.Summary.PeakPrice, + PeakFee: report.Summary.PublicConsumptionPeakFee, + Flat: report.Summary.PublicConsumptionFlat, + FlatPrice: report.Summary.FlatPrice, + FlatFee: report.Summary.PublicConsumptionFlatFee, + Valley: report.Summary.PublicConsumptionValley, + ValleyPrice: report.Summary.ValleyPrice, + ValleyFee: report.Summary.PublicConsumptionValleyFee, + Proportion: report.Summary.PublicConsumptionProportion.Decimal, } otherCollection := model.OtherShouldCollectionPart{ - MaintenanceFee: summary.MaintenanceOverall, - BasicFees: summary.BasicFee.Add(summary.AdjustFee), + MaintenanceFee: report.Summary.MaintenanceOverall, + BasicFees: report.Summary.BasicFee.Add(report.Summary.AdjustFee), } finalMaintenance := lossPart.ConsumptionFee.Add(publicSummary.ConsumptionFee).Add(otherCollection.MaintenanceFee.Decimal).Add(otherCollection.BasicFees) var maintenancePrice = decimal.Zero @@ -606,8 +687,8 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity maintenanceProportion = finalMaintenance.Div(paidPart.OverallFee.Add(otherCollection.MaintenanceFee.Decimal)).RoundBank(8) } var priceRatio = decimal.Zero - if !summary.OverallPrice.Decimal.Equal(decimal.Zero) { - priceRatio = maintenancePrice.Div(summary.OverallPrice.Decimal).RoundBank(8) + if !report.Summary.OverallPrice.Decimal.Equal(decimal.Zero) { + priceRatio = maintenancePrice.Div(report.Summary.OverallPrice.Decimal).RoundBank(8) } maintenanceFees := model.MaintenancePart{ BasicFees: otherCollection.BasicFees, @@ -620,8 +701,8 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity PriceRatio: priceRatio, } endUsers := lo.Map( - endUserDetails, - func(elem model.EndUserDetail, index int) model.EndUserSummary { + report.EndUsers, + func(elem *model.EndUserDetail, index int) model.EndUserSummary { return model.EndUserSummary{ CustomerName: elem.CustomerName, Address: elem.Address, @@ -640,9 +721,9 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity ) publicity := &model.Publicity{ - Report: *reportIndex, - Park: *parkDetail, - User: *userDetail, + Report: *report, + Park: *report.Park, + User: *report.Park.Enterprise, Paid: paidPart, EndUser: endUserSummary, Loss: lossPart, @@ -651,7 +732,7 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity Maintenance: maintenanceFees, EndUserDetails: endUsers, } - cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity_%s", reportId), "report", "park"}, "publicity", reportId) + cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity:%s", reportId), fmt.Sprintf("report:%s", reportId), "report", "park"}, "publicity", reportId) return publicity, nil }