enhance(enduser):基本完成终端用户表计在一个时间阶段内的统计功能。
This commit is contained in:
parent
f8f8a0ced1
commit
f4ee7cf8a4
|
@ -4,6 +4,7 @@ import (
|
|||
"database/sql"
|
||||
"electricity_bill_calc/excel"
|
||||
"electricity_bill_calc/global"
|
||||
"electricity_bill_calc/model"
|
||||
"electricity_bill_calc/response"
|
||||
"electricity_bill_calc/security"
|
||||
"electricity_bill_calc/service"
|
||||
|
@ -21,6 +22,7 @@ func InitializeEndUserController(router *gin.Engine) {
|
|||
router.GET("/report/:rid/meter/template", downloadEndUserRegisterTemplate)
|
||||
router.POST("/report/:rid/meter/batch", security.EnterpriseAuthorize, uploadEndUserRegisterTemplate)
|
||||
router.PUT("/report/:rid/submeter/:pid/:mid", security.EnterpriseAuthorize, modifyEndUserRegisterRecord)
|
||||
router.GET("/end/user/adjusts", security.MustAuthenticated, statEndUserInPeriod)
|
||||
}
|
||||
|
||||
func fetchEndUserInReport(c *gin.Context) {
|
||||
|
@ -224,3 +226,33 @@ func modifyEndUserRegisterRecord(c *gin.Context) {
|
|||
}
|
||||
result.Success("指定终端用户抄表记录已经更新。")
|
||||
}
|
||||
|
||||
func statEndUserInPeriod(c *gin.Context) {
|
||||
result := response.NewResult(c)
|
||||
session, err := _retreiveSession(c)
|
||||
if err != nil {
|
||||
result.Unauthorized(err.Error())
|
||||
return
|
||||
}
|
||||
requestUser := lo.
|
||||
If(session.Type == model.USER_TYPE_ENT, session.Uid).
|
||||
Else(c.DefaultQuery("user", ""))
|
||||
requestPark := c.DefaultQuery("park", "")
|
||||
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||
if !ensureParkBelongs(c, result, requestPark) {
|
||||
result.Unauthorized("不能获取不属于自己的园区。")
|
||||
return
|
||||
}
|
||||
}
|
||||
startDate := c.DefaultQuery("start", "")
|
||||
endDate := c.DefaultQuery("end", "")
|
||||
stat, err := service.EndUserService.StatEndUserRecordInPeriod(requestUser, requestPark, startDate, endDate)
|
||||
if err != nil {
|
||||
result.Error(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
result.Success(
|
||||
"已经完成终端用户的费用统计",
|
||||
gin.H{"details": stat},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -186,6 +186,7 @@ func statAdditionalCharges(c *gin.Context) {
|
|||
requestPark := c.DefaultQuery("park", "")
|
||||
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||
if !ensureParkBelongs(c, result, requestPark) {
|
||||
result.Unauthorized("不能获取不属于自己的园区。")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,7 +190,6 @@ func batchImport04kVMeterArchive(c *gin.Context) {
|
|||
mergedMeters := lo.Map(records, func(meter model.Meter04KV, index int) model.Meter04KV {
|
||||
meter.ParkId = requestParkId
|
||||
meter.Enabled = true
|
||||
meter.WillDilute = false
|
||||
return meter
|
||||
})
|
||||
errs = service.Meter04kVService.DuplicateMeterCodeValidate(mergedMeters)
|
||||
|
|
|
@ -56,6 +56,8 @@ type EndUserDetail struct {
|
|||
FinalCharge decimal.NullDecimal `bun:"type:numeric" json:"finalCharge"`
|
||||
Initialize bool `bun:"-" json:"-"`
|
||||
Origin *Meter04KV `bun:"rel:belongs-to,join:park_id=park_id,join:meter_04kv_id=code" json:"-"`
|
||||
Report *Report `bun:"rel:belongs-to,join:report_id=id" json:"-"`
|
||||
Park *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||
}
|
||||
|
||||
var _ bun.BeforeAppendModelHook = (*EndUserDetail)(nil)
|
||||
|
@ -110,3 +112,20 @@ type EndUserImport struct {
|
|||
AdjustFlat decimal.NullDecimal `excel:"adjustFlat"`
|
||||
AdjustValley decimal.NullDecimal `excel:"adjustValley"`
|
||||
}
|
||||
|
||||
type EndUserPeriodStat struct {
|
||||
CustomerName string `json:"customerName"`
|
||||
Address string `json:"address"`
|
||||
MeterId string `bun:"meter_04kv_id" json:"meterId"`
|
||||
IsPublicMeter bool `bun:"public_meter" json:"isPublicMeter"`
|
||||
Overall decimal.NullDecimal `json:"overall"`
|
||||
Critical decimal.NullDecimal `json:"critical"`
|
||||
Peak decimal.NullDecimal `json:"peak"`
|
||||
Valley decimal.NullDecimal `json:"valley"`
|
||||
OverallFee decimal.NullDecimal `json:"overallFee"`
|
||||
CriticalFee decimal.NullDecimal `json:"criticalFee"`
|
||||
PeakFee decimal.NullDecimal `json:"peakFee"`
|
||||
ValleyFee decimal.NullDecimal `json:"valleyFee"`
|
||||
AdjustFee decimal.NullDecimal `bun:"final_diluted" json:"adjustFee"`
|
||||
AdjustProportion decimal.NullDecimal `bun:"-" json:"adjustProportion"`
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ type Meter04KV struct {
|
|||
Ratio decimal.Decimal `bun:"type:numeric,notnull" json:"ratio" excel:"ratio"`
|
||||
Seq int64 `bun:"type:bigint,notnull" json:"seq" excel:"seq"`
|
||||
IsPublicMeter bool `bun:"public_meter,notnull" json:"isPublicMeter" excel:"public"`
|
||||
WillDilute bool `bun:"dilute,notnull" json:"willDilute" excel:"dilute"`
|
||||
Enabled bool `bun:",notnull" json:"enabled"`
|
||||
ParkDetail *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ func NewEmptyDate() Date {
|
|||
panic(err)
|
||||
}
|
||||
return Date{
|
||||
Time: time.Date(2000, 1, 1, 0, 0, 0, 0, loc),
|
||||
Time: time.Time{}.In(loc),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,18 @@ func ParseDate(t string) (Date, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (d Date) IsEmpty() bool {
|
||||
return d.Time.IsZero()
|
||||
}
|
||||
|
||||
func (d Date) Format(fmt string) string {
|
||||
return d.Time.Format(fmt)
|
||||
}
|
||||
|
||||
func (d Date) ToString() string {
|
||||
return d.Time.Format("2006-01-02")
|
||||
}
|
||||
|
||||
var _ driver.Valuer = (*Date)(nil)
|
||||
|
||||
func (d Date) Value() (driver.Value, error) {
|
||||
|
|
|
@ -13,7 +13,9 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"github.com/samber/lo"
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/uptrace/bun"
|
||||
|
@ -353,3 +355,112 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader)
|
|||
cache.AbolishRelation("end_user_detail")
|
||||
return errs
|
||||
}
|
||||
|
||||
func (es _EndUserService) StatEndUserRecordInPeriod(requestUser, requestPark, startDate, endDate string) ([]model.EndUserPeriodStat, error) {
|
||||
var (
|
||||
conditions = make([]string, 0)
|
||||
relations = []string{
|
||||
fmt.Sprintf("park:%s", requestPark),
|
||||
"end_user_detail",
|
||||
}
|
||||
cond = global.DB.NewSelect().
|
||||
Model((*model.EndUserDetail)(nil)).
|
||||
Relation("Report", func(sq *bun.SelectQuery) *bun.SelectQuery {
|
||||
return sq.ExcludeColumn("*")
|
||||
}).
|
||||
Relation("Park", func(sq *bun.SelectQuery) *bun.SelectQuery {
|
||||
return sq.ExcludeColumn("*")
|
||||
})
|
||||
)
|
||||
if len(requestUser) > 0 {
|
||||
cond = cond.Where("Park.user_id = ?", requestUser)
|
||||
conditions = append(conditions, requestUser)
|
||||
} else {
|
||||
conditions = append(conditions, "_")
|
||||
}
|
||||
if len(requestPark) > 0 {
|
||||
cond = cond.Where("eud.park_id = ?", requestPark)
|
||||
conditions = append(conditions, requestPark)
|
||||
} else {
|
||||
conditions = append(conditions, "_")
|
||||
}
|
||||
if len(startDate) > 0 {
|
||||
parseTime, err := time.Parse("2006-01", startDate)
|
||||
if err != nil {
|
||||
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("不能解析给定的参数[startDate],%w", err)
|
||||
}
|
||||
start := model.NewDate(parseTime)
|
||||
cond = cond.Where("report.period >= ?::date", start.ToString())
|
||||
conditions = append(conditions, startDate)
|
||||
} else {
|
||||
conditions = append(conditions, "_")
|
||||
}
|
||||
if len(endDate) > 0 {
|
||||
parseTime, err := time.Parse("2006-01", endDate)
|
||||
if err != nil {
|
||||
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("不能解析给定的参数[endDate],%w", err)
|
||||
}
|
||||
end := model.NewDate(parseTime)
|
||||
cond = cond.Where("report.period <= ?::date", end.ToString())
|
||||
conditions = append(conditions, endDate)
|
||||
}
|
||||
if cached, err := cache.RetreiveSearch[[]model.EndUserPeriodStat]("end_user_stat", conditions...); cached != nil && err == nil {
|
||||
return *cached, nil
|
||||
}
|
||||
ctx, cancel := global.TimeoutContext(120)
|
||||
defer cancel()
|
||||
var endUserSums []model.EndUserPeriodStat
|
||||
err := cond.Column("eud.meter_04kv_id").
|
||||
ColumnExpr("sum(?) as overall", bun.Ident("eud.overall")).
|
||||
ColumnExpr("sum(?) as overall_fee", bun.Ident("eud.overall_fee")).
|
||||
ColumnExpr("sum(?) as critical", bun.Ident("eud.critical")).
|
||||
ColumnExpr("sum(?) as critical_fee", bun.Ident("eud.critical_fee")).
|
||||
ColumnExpr("sum(?) as peak", bun.Ident("eud.peak")).
|
||||
ColumnExpr("sum(?) as peak_fee", bun.Ident("eud.peak_fee")).
|
||||
ColumnExpr("sum(?) as valley", bun.Ident("eud.valley")).
|
||||
ColumnExpr("sum(?) as valley_fee", bun.Ident("eud.valley_fee")).
|
||||
ColumnExpr("sum(?) as final_diluted", bun.Ident("eud.final_diluted")).
|
||||
Group("eud.meter_04kv_id").
|
||||
Scan(ctx, &endUserSums)
|
||||
if err != nil {
|
||||
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("未能完成终端用户在指定期限内的统计,%w", err)
|
||||
}
|
||||
meterIds := lo.Reduce(
|
||||
endUserSums,
|
||||
func(acc mapset.Set[string], elem model.EndUserPeriodStat, _ int) mapset.Set[string] {
|
||||
acc.Add(elem.MeterId)
|
||||
return acc
|
||||
},
|
||||
mapset.NewSet[string](),
|
||||
)
|
||||
meterArchives := make([]model.Meter04KV, 0)
|
||||
if len(meterIds.ToSlice()) > 0 {
|
||||
err = global.DB.NewSelect().Model(&meterArchives).
|
||||
Where("code in (?)", bun.In(meterIds.ToSlice())).
|
||||
Scan(ctx)
|
||||
if err != nil {
|
||||
return make([]model.EndUserPeriodStat, 0), fmt.Errorf("未能获取到终端表计的最新基础档案,%w", err)
|
||||
}
|
||||
}
|
||||
filledStats := lo.Map(
|
||||
endUserSums,
|
||||
func(elem model.EndUserPeriodStat, _ int) model.EndUserPeriodStat {
|
||||
archive, has := lo.Find(meterArchives, func(meter model.Meter04KV) bool {
|
||||
return meter.Code == elem.MeterId
|
||||
})
|
||||
if has {
|
||||
elem.Address = *archive.Address
|
||||
elem.CustomerName = *archive.CustomerName
|
||||
elem.IsPublicMeter = archive.IsPublicMeter
|
||||
}
|
||||
if !elem.Overall.Decimal.IsZero() {
|
||||
elem.AdjustProportion = decimal.NewNullDecimal(
|
||||
elem.AdjustFee.Decimal.Div(elem.OverallFee.Decimal).RoundBank(8),
|
||||
)
|
||||
}
|
||||
return elem
|
||||
},
|
||||
)
|
||||
cache.CacheSearch(filledStats, relations, "end_user_stat", conditions...)
|
||||
return filledStats, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user