refactor(report):报表的服务功能基本完成迁移。

This commit is contained in:
徐涛 2022-09-16 17:27:10 +08:00
parent 7ce9abe1de
commit d778c4d3f3

View File

@ -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(&currentActivatedCustomers)
err = global.DB.NewSelect().Model(&currentActivatedCustomers).
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()
// 首先删除所有预定义的部分条件是指定报表IDSourceID不为空。
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
}