diff --git a/service/calculate.go b/service/calculate.go index 0e294ba..d31155a 100644 --- a/service/calculate.go +++ b/service/calculate.go @@ -1,9 +1,11 @@ package service import ( + "electricity_bill_calc/cache" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" "electricity_bill_calc/model" + "fmt" "github.com/shopspring/decimal" "xorm.io/builder" @@ -241,5 +243,6 @@ func (_CalculateService) ComprehensivelyCalculateReport(reportId string) (err er tx.Rollback() return } + cache.AbolishRelation(fmt.Sprintf("publicity_%s", reportId)) return } diff --git a/service/end_user.go b/service/end_user.go index e21f8f7..86ba060 100644 --- a/service/end_user.go +++ b/service/end_user.go @@ -1,6 +1,7 @@ package service import ( + "electricity_bill_calc/cache" "electricity_bill_calc/config" "electricity_bill_calc/excel" "electricity_bill_calc/exceptions" @@ -8,6 +9,7 @@ import ( "electricity_bill_calc/model" "fmt" "io" + "strconv" "github.com/samber/lo" "github.com/shopspring/decimal" @@ -21,6 +23,8 @@ type _EndUserService struct{} var EndUserService _EndUserService func (_EndUserService) SearchEndUserRecord(reportId, keyword string, page int) ([]model.EndUserDetail, int64, error) { + var conditions = make([]string, 0) + conditions = append(conditions, reportId, strconv.Itoa(page)) cond := builder.NewCond().And(builder.Eq{"report_id": reportId}) if len(keyword) > 0 { cond = cond.And( @@ -29,39 +33,61 @@ func (_EndUserService) SearchEndUserRecord(reportId, keyword string, page int) ( Or(builder.Like{"contact_phone", keyword}). Or(builder.Like{"meter_04kv_id", keyword}), ) + conditions = append(conditions, keyword) } - total, err := global.DBConn. - Table(&model.EndUserDetail{}). - Where(cond). - Count() - if err != nil { - return make([]model.EndUserDetail, 0), -1, err + var ( + total int64 + err error + ) + if cachedTotal, _ := cache.RetreiveCount("end_user_detail", conditions...); cachedTotal != -1 { + total = cachedTotal + } else { + total, err = global.DBConn. + Table(&model.EndUserDetail{}). + Where(cond). + Count() + if err != nil { + return make([]model.EndUserDetail, 0), -1, err + } + cache.CacheCount([]string{"end_user", "report", "park"}, "end_user_detail", total, conditions...) } startItem := (page - 1) * config.ServiceSettings.ItemsPageSize + if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", conditions...); cachedEndUsers != nil { + return *cachedEndUsers, total, nil + } endUsers := make([]model.EndUserDetail, 0) err = global.DBConn. Where(cond). Limit(config.ServiceSettings.ItemsPageSize, startItem). Asc("seq"). Find(&endUsers) + cache.CacheSearch(endUsers, []string{"end_user", "report", "park"}, "end_user_detail", conditions...) return endUsers, total, err } func (_EndUserService) AllEndUserRecord(reportId string) ([]model.EndUserDetail, error) { + if cachedEndUsers, _ := cache.RetreiveSearch[[]model.EndUserDetail]("end_user_detail", "report", reportId); cachedEndUsers != nil { + return *cachedEndUsers, nil + } users := make([]model.EndUserDetail, 0) err := global.DBConn. Where(builder.Eq{"report_id": reportId}). Asc("seq"). Find(&users) + cache.CacheSearch(users, []string{"end_user_detail", "report", "park"}, "end_user_detail", "report", reportId) return users, err } func (_EndUserService) FetchSpecificEndUserRecord(reportId, parkId, meterId string) (*model.EndUserDetail, error) { + if cachedEndUser, _ := cache.RetreiveEntity[model.EndUserDetail]("end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId)); cachedEndUser != nil { + return cachedEndUser, nil + } record := new(model.EndUserDetail) _, err := global.DBConn. ID(schemas.NewPK(reportId, parkId, meterId)). NoAutoCondition(). Get(record) + cache.CacheEntity(record, []string{"end_user_detail", "report", "park"}, "end_user_detail", fmt.Sprintf("%s_%s_%s", reportId, parkId, meterId)) return record, err } @@ -86,6 +112,7 @@ func (_EndUserService) UpdateEndUserRegisterRecord(tx *xorm.Session, record mode "valley", ). Update(record) + cache.AbolishRelation("end_user_detail") return } @@ -155,6 +182,7 @@ func (es _EndUserService) BatchImportNonPVRegister(reportId string, file io.Read tx.Rollback() errs.AddError(es.newVirtualExcelAnalysisError(err)) } + cache.AbolishRelation("end_user_detail") return errs } @@ -220,5 +248,6 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader) tx.Rollback() errs.AddError(es.newVirtualExcelAnalysisError(err)) } + cache.AbolishRelation("end_user_detail") return errs } diff --git a/service/report.go b/service/report.go index ee1ab8b..dc7b3cc 100644 --- a/service/report.go +++ b/service/report.go @@ -1,12 +1,14 @@ package service import ( + "electricity_bill_calc/cache" "electricity_bill_calc/config" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" "electricity_bill_calc/model" "electricity_bill_calc/tools" "fmt" + "strconv" "time" "github.com/fufuok/utils" @@ -21,6 +23,9 @@ type _ReportService struct{} var ReportService _ReportService 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"). @@ -46,18 +51,24 @@ func (_ReportService) FetchParksWithNewestReport(uid string) ([]model.ParkNewest }, make(map[string]model.ParkNewestReport, 0), ) + cache.CacheSearch(reducedParks, []string{"park", "report"}, "park_newest_report", uid) return lo.Values(reducedParks), nil } func (_ReportService) IsNewPeriodValid(uid string, period time.Time) (bool, error) { reports := make([]model.Report, 0) - err := global.DBConn. - Table("report").Alias("r"). - Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). - Where(builder.Eq{"p.user_id": uid}). - Find(&reports) - if err != nil { - return false, nil + if cachedReport, _ := cache.RetreiveSearch[[]model.Report]("report", "user", uid); 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}). + Find(&reports) + if err != nil { + return false, nil + } + cache.CacheSearch(reports, []string{"report", "park"}, "park", "user", uid) } // 检查给定的期数在目前的记录中是否已经存在 exists := lo.Reduce( @@ -223,16 +234,21 @@ func (_ReportService) InitializeNewReport(parkId string, period time.Time) (stri tx.Rollback() return "", err } + cache.AbolishRelation("report") return newReport.Id, nil } 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) 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 } else { return nil, nil @@ -240,16 +256,23 @@ func (_ReportService) RetreiveReportIndex(rid string) (*model.Report, error) { } func (_ReportService) RetreiveReportSummary(rid string) (*model.ReportSummary, error) { + if cachedSummary, _ := cache.RetreiveEntity[model.ReportSummary]("report_summary", rid); cachedSummary != nil { + return cachedSummary, nil + } var summary = new(model.ReportSummary) _, err := global.DBConn.ID(rid).NoAutoCondition().Get(summary) if err != nil { return nil, err } + 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) + if err == nil { + cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId)) + } return err } @@ -292,21 +315,27 @@ func (_ReportService) CalculateSummaryAndFinishStep(reportId string) error { tx.Rollback() return err } + cache.AbolishRelation(fmt.Sprintf("report_%s", summary.ReportId)) return nil } func (_ReportService) FetchWillDulutedMaintenanceFees(reportId string) ([]model.WillDilutedFee, error) { + if cachedFees, _ := cache.RetreiveSearch[[]model.WillDilutedFee]("will_diluted_fee", "report", reportId); cachedFees != nil { + return *cachedFees, nil + } fees := make([]model.WillDilutedFee, 0) err := global.DBConn.Where(builder.Eq{"report_id": reportId}).Asc("created_at").Find(&fees) 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) return fees, nil } func (_ReportService) CreateTemporaryWillDilutedMaintenanceFee(fee model.WillDilutedFee) error { fee.Id = utils.UUIDString() _, err := global.DBConn.Insert(fee) + cache.AbolishRelation("will_diluted_fee") return err } @@ -333,38 +362,47 @@ func (_ReportService) BatchSaveMaintenanceFee(reportId string, fees []model.Will tx.Rollback() return err } + cache.AbolishRelation("will_diluted_fee") 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") return } func (_ReportService) DeleteWillDilutedFee(fee string) (err error) { _, err = global.DBConn.ID(fee).NoAutoCondition().Delete(new(model.WillDilutedFee)) + cache.AbolishRelation("will_diluted_fee") return } func (_ReportService) ProgressReportWillDilutedFee(report model.Report) (err error) { report.StepState.WillDiluted = true _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) + cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) return } func (_ReportService) ProgressReportRegisterEndUser(report model.Report) (err error) { report.StepState.Submeter = true _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) + cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) return } func (_ReportService) ProgressReportCalculate(report model.Report) (err error) { report.StepState.Calculate = true _, err = global.DBConn.ID(report.Id).Cols("step_state").Update(report) + cache.AbolishRelation(fmt.Sprintf("report_%s", report.Id)) return } 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"). @@ -378,6 +416,7 @@ func (_ReportService) RetreiveParkEndUserMeterType(reportId string) (int, error) 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 } @@ -386,19 +425,26 @@ func (_ReportService) PublishReport(report model.Report) (err error) { 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)) return } func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword string, requestPeriod *time.Time, requestPage int) ([]model.JoinedReportForWithdraw, int64, error) { + var conditions = make([]string, 0) + conditions = append(conditions, strconv.Itoa(requestPage)) cond := builder.NewCond().And(builder.Eq{"r.published": true}) if len(requestUser) > 0 { cond = cond.And(builder.Eq{"u.id": requestUser}) + conditions = append(conditions, requestUser) } if len(requestPark) > 0 { cond = cond.And(builder.Eq{"p.id": requestPark}) + conditions = append(conditions, requestPark) } if requestPeriod != nil { cond = cond.And(builder.Eq{"r.period": *requestPeriod}) + conditions = append(conditions, strconv.FormatInt(requestPeriod.Unix(), 10)) } if len(requestKeyword) > 0 { cond = cond.And( @@ -409,17 +455,30 @@ func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword stri Or(builder.Like{"u.address", requestKeyword}). Or(builder.Like{"p.address", requestKeyword}), ) + conditions = append(conditions, requestKeyword) } - 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 + var ( + total int64 + err error + ) + if cachedTotal, _ := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 { + 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 + } + cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...) } startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize + if cachedRecords, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_report_for_withdraw", conditions...); cachedRecords != nil { + return *cachedRecords, total, nil + } records := make([]model.JoinedReportForWithdraw, 0) err = global.DBConn. Table("report").Alias("r"). @@ -428,10 +487,14 @@ func (_ReportService) SearchReport(requestUser, requestPark, requestKeyword stri Where(cond). Limit(config.ServiceSettings.ItemsPageSize, startItem). Find(&records) + cache.CacheSearch(records, []string{"report", "park"}, "join_report_for_withdraw", conditions...) return records, total, err } func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity, error) { + if cachedPublicity, _ := cache.RetreiveEntity[model.Publicity]("publicity", reportId); cachedPublicity != nil { + return cachedPublicity, nil + } // 资料准备 var reportIndex = new(model.Report) has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(reportIndex) @@ -570,7 +633,7 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity }, ) - return &model.Publicity{ + publicity := &model.Publicity{ Report: *reportIndex, Park: *parkDetail, User: *userDetail, @@ -581,5 +644,8 @@ func (_ReportService) AssembleReportPublicity(reportId string) (*model.Publicity OtherCollections: otherCollection, Maintenance: maintenanceFees, EndUserDetails: endUsers, - }, nil + } + cache.CacheEntity(publicity, []string{fmt.Sprintf("publicity_%s", reportId), "report", "park"}, "publicity", reportId) + + return publicity, nil } diff --git a/service/statistics.go b/service/statistics.go index a3730e8..368eba1 100644 --- a/service/statistics.go +++ b/service/statistics.go @@ -1,6 +1,7 @@ package service import ( + "electricity_bill_calc/cache" "electricity_bill_calc/global" "electricity_bill_calc/model" @@ -13,24 +14,41 @@ type _StatisticsService struct{} var StatisticsService _StatisticsService func (_StatisticsService) EnabledEnterprises() (int64, error) { - return global.DBConn. + if cachedCount, _ := cache.RetreiveCount("enabled_ent"); cachedCount != -1 { + return cachedCount, nil + } + c, err := global.DBConn. Table(new(model.User)). Where(builder.Eq{"type": 0, "enabled": true}). Count() + if err == nil { + cache.CacheCount([]string{"user"}, "enabled_ent", c) + } + return c, err } func (_StatisticsService) EnabledParks(userIds ...string) (int64, error) { + if cachedParks, _ := cache.RetreiveCount("enabled_parks", userIds...); cachedParks != -1 { + return cachedParks, nil + } cond := builder.NewCond().And(builder.Eq{"enabled": true}) if len(userIds) > 0 { cond = cond.And(builder.Eq{"user_id": userIds}) } - return global.DBConn. + c, err := global.DBConn. Table(new(model.Park)). Where(cond). Count() + if err == nil { + cache.CacheCount([]string{"user", "park"}, "enabled_parks", c, userIds...) + } + return c, err } func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPeriodStatistics, error) { + if cachedState, _ := cache.RetreiveSearch[[]model.ParkPeriodStatistics]("park_period_stat", userIds...); cachedState != nil { + return *cachedState, nil + } cond := builder.NewCond().And(builder.Eq{"p.enabled": true, "r.published": true}) if len(userIds) > 0 { cond = cond.And(builder.Eq{"p.user_id": userIds}) @@ -58,5 +76,6 @@ func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPerio groupedParks[p.Id] = p } } + cache.CacheSearch(lo.Values(groupedParks), []string{"user", "park"}, "park_period_stat", userIds...) return lo.Values(groupedParks), nil } diff --git a/service/withdraw.go b/service/withdraw.go index 3c519cf..39d68f3 100644 --- a/service/withdraw.go +++ b/service/withdraw.go @@ -1,10 +1,13 @@ package service import ( + "electricity_bill_calc/cache" "electricity_bill_calc/config" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" "electricity_bill_calc/model" + "fmt" + "strconv" "time" "github.com/samber/lo" @@ -56,11 +59,15 @@ func (_WithdrawService) ApplyWithdraw(reportId string) (bool, error) { if err != nil { return false, err } + cache.AbolishRelation("report") + cache.AbolishRelation(fmt.Sprintf("publicity_%s", reportId)) return true, nil } func (_WithdrawService) FetchPagedWithdrawApplies(page int, keyword string) ([]model.JoinedReportForWithdraw, int64, error) { + var conditions = make([]string, 0) cond := builder.NewCond() + conditions = append(conditions, strconv.Itoa(int(model.REPORT_WITHDRAW_APPLIED)), strconv.Itoa(page)) cond = cond.And(builder.Eq{"r.withdraw": model.REPORT_WITHDRAW_APPLIED}) if len(keyword) > 0 { cond = cond.And( @@ -71,18 +78,31 @@ func (_WithdrawService) FetchPagedWithdrawApplies(page int, keyword string) ([]m builder.Like{"u.abbr", keyword}, ), ) + conditions = append(conditions, keyword) } var reports = make([]model.JoinedReportForWithdraw, 0) - total, err := global.DBConn. - Table(new(model.JoinedReportForWithdraw)).Alias("r"). - Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). - Join("INNER", []string{"user_detail", "u"}, "p.user_id=u.id"). - Where(cond). - Count() - if err != nil { - return nil, -1, err + var ( + total int64 + err error + ) + if cachedTotal, _ := cache.RetreiveCount("join_report_for_withdraw", conditions...); cachedTotal != -1 { + total = cachedTotal + } else { + total, err = global.DBConn. + Table(new(model.JoinedReportForWithdraw)).Alias("r"). + Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). + Join("INNER", []string{"user_detail", "u"}, "p.user_id=u.id"). + Where(cond). + Count() + if err != nil { + return nil, -1, err + } + cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...) } startItem := (page - 1) * config.ServiceSettings.ItemsPageSize + if cachedReports, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_user_detail", conditions...); cachedReports != nil { + return *cachedReports, total, err + } err = global.DBConn. Alias("r"). Join("INNER", []string{"park", "p"}, "r.park_id=p.id"). @@ -90,6 +110,7 @@ func (_WithdrawService) FetchPagedWithdrawApplies(page int, keyword string) ([]m Where(cond). Limit(config.ServiceSettings.ItemsPageSize, startItem). Find(&reports) + cache.CacheSearch(reports, []string{"report", "park"}, "join_report_for_withdraw", conditions...) return reports, total, err } @@ -108,14 +129,22 @@ func (_WithdrawService) AuditWithdraw(reportId string, granted bool) error { report.Published = false } _, err = global.DBConn.ID(report.Id).Cols("withdraw", "last_withdraw_audit_at", "published").Update(report) + cache.AbolishRelation("report") return err } func (_WithdrawService) AuditWaits() (int64, error) { + if cachedWaits, _ := cache.RetreiveCount("withdraw_waits"); cachedWaits != -1 { + return cachedWaits, nil + } cond := builder.NewCond() cond = cond.And(builder.Eq{"withdraw": model.REPORT_WITHDRAW_APPLIED}) - return global.DBConn. + total, err := global.DBConn. Table(new(model.JoinedReportForWithdraw)). Where(cond). Count() + if err == nil { + cache.CacheCount([]string{"report", "park"}, "withdraw_waits", total) + } + return total, err }