From e250ef67920e536b325d56f7f22057b90f495653 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Fri, 16 Sep 2022 22:17:19 +0800 Subject: [PATCH] =?UTF-8?q?refactor(withdraw):=E6=8A=A5=E8=A1=A8=E6=92=A4?= =?UTF-8?q?=E5=9B=9E=E7=B3=BB=E5=88=97=E5=8A=9F=E8=83=BD=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=BF=81=E7=A7=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- service/withdraw.go | 178 +++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 83 deletions(-) diff --git a/service/withdraw.go b/service/withdraw.go index 84f4ac1..512ccd4 100644 --- a/service/withdraw.go +++ b/service/withdraw.go @@ -5,131 +5,143 @@ import ( "electricity_bill_calc/config" "electricity_bill_calc/exceptions" "electricity_bill_calc/global" + "electricity_bill_calc/logger" "electricity_bill_calc/model" "fmt" "strconv" "time" "github.com/samber/lo" - "xorm.io/builder" + "github.com/uptrace/bun" + "go.uber.org/zap" ) -type _WithdrawService struct{} +type _WithdrawService struct { + l *zap.Logger +} -var WithdrawService _WithdrawService +var WithdrawService = _WithdrawService{ + l: logger.Named("Service", "Withdraw"), +} func (_WithdrawService) ApplyWithdraw(reportId string) (bool, error) { - var report = new(model.Report) - has, err := global.DBConn.ID(reportId).Get(report) - if err != nil { - return false, err - } - if !has { - return false, exceptions.NewNotFoundError("指定报表未能找到") + ctx, cancel := global.TimeoutContext() + defer cancel() + + var report *model.Report + err := global.DB.NewSelect().Model(report). + Where("id = ?", reportId). + Scan(ctx) + if err != nil || report == nil { + return false, exceptions.NewNotFoundErrorFromError("指定报表未能找到", err) } if !report.Published { return false, exceptions.NewImproperOperateError("指定报表尚未发布。") } - reports := make([]model.Report, 0) - err = global.DBConn. - Where(builder.Eq{"park_id": report.ParkId}). - Find(&reports) + var maxPublished *time.Time + err = global.DB.NewSelect().Model((*model.Report)(nil)). + ColumnExpr("max(period)"). + Where("park_id = ?", report.ParkId). + Where("published = ?", true). + Scan(ctx, maxPublished) if err != nil { return false, exceptions.NewNotFoundError("未能找到匹配的系列报表。") } - maxPublished := lo.Reduce( - reports, - func(acc *time.Time, elem model.Report, index int) *time.Time { - if elem.Published { - if acc == nil || (acc != nil && elem.Period.After(*acc)) { - return &elem.Period - } - } - return acc - }, - nil, - ) - if !report.Period.Equal(*maxPublished) { + if maxPublished != nil && !report.Period.Equal(*maxPublished) { return false, exceptions.NewImproperOperateError("申请撤回的报表必须是最新已发布的报表。") } report.Withdraw = model.REPORT_WITHDRAW_APPLIED report.LastWithdrawAppliedAt = lo.ToPtr(time.Now()) - _, err = global.DBConn.ID(report.Id).Cols("withdraw", "last_withdraw_applied_at").Update(report) + _, err = global.DB.NewUpdate().Model(report). + WherePK(). + Column("withdraw", "last_withdraw_applied_at"). + Exec(ctx) if err != nil { return false, err } - cache.AbolishRelation("report") - cache.AbolishRelation(fmt.Sprintf("publicity_%s", reportId)) + cache.AbolishRelation("withdraw_stat") + cache.AbolishRelation(fmt.Sprintf("report:%s", reportId)) + 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() + 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(int(model.REPORT_WITHDRAW_APPLIED)), strconv.Itoa(page)) - cond = cond.And(builder.Eq{"r.withdraw": model.REPORT_WITHDRAW_APPLIED}) + cond = cond.Where("r.withdraw = ?", model.REPORT_WITHDRAW_APPLIED) if len(keyword) > 0 { - cond = cond.And( - builder.Like{"p.name", keyword}. - Or( - builder.Like{"p.abbr", keyword}, - builder.Like{"u.name", keyword}, - builder.Like{"u.abbr", keyword}, - ), - ) + keywordCond := "%" + keyword + "%" + cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Where("p.name like ?", keywordCond). + WhereOr("p.abbr like ?", keywordCond). + WhereOr("d.name like ?", keywordCond). + WhereOr("d.abbr like ?", keywordCond) + }) conditions = append(conditions, keyword) } - var reports = make([]model.JoinedReportForWithdraw, 0) - 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(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 + if cachedReports, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_user_detail", conditions...); cachedReports != nil { + return *cachedReports, cachedTotal, err } - cache.CacheCount([]string{"report", "park"}, "join_report_for_withdraw", total, conditions...) } + + ctx, cancel := global.TimeoutContext() + defer cancel() startItem := (page - 1) * config.ServiceSettings.ItemsPageSize - if cachedReports, _ := cache.RetreiveSearch[[]model.JoinedReportForWithdraw]("join_user_detail", conditions...); cachedReports != nil { - return *cachedReports, total, err + total, err := cond.Limit(config.ServiceSettings.ItemsPageSize). + Offset(startItem). + ScanAndCount(ctx) + + var ( + joinedReports = make([]model.JoinedReportForWithdraw, 0) + relations = []string{"report", "park"} + ) + for _, r := range reports { + joinedReports = append(joinedReports, model.JoinedReportForWithdraw{ + Report: r, + Park: model.FromPark(*r.Park), + User: model.FromUserDetail(*r.Park.Enterprise), + }) + relations = append(relations, fmt.Sprintf("report:%s", r.Id), fmt.Sprintf("publicity:%s", r.Id)) } - err = global.DBConn. - 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). - Limit(config.ServiceSettings.ItemsPageSize, startItem). - Find(&reports) - cache.CacheSearch(reports, []string{"report", "park"}, "join_report_for_withdraw", conditions...) - return reports, total, err + + cache.CacheCount(relations, "join_report_for_withdraw", int64(total), conditions...) + cache.CacheSearch(joinedReports, relations, "join_report_for_withdraw", conditions...) + return joinedReports, int64(total), err } func (_WithdrawService) AuditWithdraw(reportId string, granted bool) 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). + Where("id = ?", reportId). + Scan(ctx) if err != nil { - return err - } - if !has { - return exceptions.NewNotFoundError("指定公示报表未找到。") + return exceptions.NewNotFoundErrorFromError("指定公示报表未找到。", err) } report.Withdraw = lo.If(granted, model.REPORT_WITHDRAW_GRANTED).Else(model.REPORT_WITHDRAW_DENIED) report.LastWithdrawAuditAt = lo.ToPtr(time.Now()) if granted { report.Published = false } - _, err = global.DBConn.ID(report.Id).Cols("withdraw", "last_withdraw_audit_at", "published").Update(report) - cache.AbolishRelation("report") + _, err = global.DB.NewUpdate().Model(report). + WherePK(). + Column("withdraw", "last_withdraw_audit_at", "published"). + Exec(ctx) + if err == nil { + cache.AbolishRelation("withdraw_stat") + cache.AbolishRelation(fmt.Sprintf("report:%s", reportId)) + } return err } @@ -137,14 +149,14 @@ func (_WithdrawService) AuditWaits() (int64, error) { if cachedWaits, err := cache.RetreiveCount("withdraw_waits"); cachedWaits != -1 && err == nil { return cachedWaits, nil } - cond := builder.NewCond() - cond = cond.And(builder.Eq{"withdraw": model.REPORT_WITHDRAW_APPLIED}) - total, err := global.DBConn. - Table(new(model.JoinedReportForWithdraw)). - Where(cond). - Count() + ctx, cancel := global.TimeoutContext() + defer cancel() + + total, err := global.DB.NewSelect().Model((*model.Report)(nil)). + Where("withdraw = ?", model.REPORT_WITHDRAW_APPLIED). + Count(ctx) if err == nil { - cache.CacheCount([]string{"report", "park"}, "withdraw_waits", total) + cache.CacheCount([]string{"withdraw_stat"}, "withdraw_waits", int64(total)) } - return total, err + return int64(total), err }