enhance(enduser):基本完成终端用户表计在一个时间阶段内的统计功能。
This commit is contained in:
parent
f8f8a0ced1
commit
f4ee7cf8a4
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"electricity_bill_calc/excel"
|
"electricity_bill_calc/excel"
|
||||||
"electricity_bill_calc/global"
|
"electricity_bill_calc/global"
|
||||||
|
"electricity_bill_calc/model"
|
||||||
"electricity_bill_calc/response"
|
"electricity_bill_calc/response"
|
||||||
"electricity_bill_calc/security"
|
"electricity_bill_calc/security"
|
||||||
"electricity_bill_calc/service"
|
"electricity_bill_calc/service"
|
||||||
|
@ -21,6 +22,7 @@ func InitializeEndUserController(router *gin.Engine) {
|
||||||
router.GET("/report/:rid/meter/template", downloadEndUserRegisterTemplate)
|
router.GET("/report/:rid/meter/template", downloadEndUserRegisterTemplate)
|
||||||
router.POST("/report/:rid/meter/batch", security.EnterpriseAuthorize, uploadEndUserRegisterTemplate)
|
router.POST("/report/:rid/meter/batch", security.EnterpriseAuthorize, uploadEndUserRegisterTemplate)
|
||||||
router.PUT("/report/:rid/submeter/:pid/:mid", security.EnterpriseAuthorize, modifyEndUserRegisterRecord)
|
router.PUT("/report/:rid/submeter/:pid/:mid", security.EnterpriseAuthorize, modifyEndUserRegisterRecord)
|
||||||
|
router.GET("/end/user/adjusts", security.MustAuthenticated, statEndUserInPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchEndUserInReport(c *gin.Context) {
|
func fetchEndUserInReport(c *gin.Context) {
|
||||||
|
@ -224,3 +226,33 @@ func modifyEndUserRegisterRecord(c *gin.Context) {
|
||||||
}
|
}
|
||||||
result.Success("指定终端用户抄表记录已经更新。")
|
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", "")
|
requestPark := c.DefaultQuery("park", "")
|
||||||
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT {
|
||||||
if !ensureParkBelongs(c, result, requestPark) {
|
if !ensureParkBelongs(c, result, requestPark) {
|
||||||
|
result.Unauthorized("不能获取不属于自己的园区。")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,7 +190,6 @@ func batchImport04kVMeterArchive(c *gin.Context) {
|
||||||
mergedMeters := lo.Map(records, func(meter model.Meter04KV, index int) model.Meter04KV {
|
mergedMeters := lo.Map(records, func(meter model.Meter04KV, index int) model.Meter04KV {
|
||||||
meter.ParkId = requestParkId
|
meter.ParkId = requestParkId
|
||||||
meter.Enabled = true
|
meter.Enabled = true
|
||||||
meter.WillDilute = false
|
|
||||||
return meter
|
return meter
|
||||||
})
|
})
|
||||||
errs = service.Meter04kVService.DuplicateMeterCodeValidate(mergedMeters)
|
errs = service.Meter04kVService.DuplicateMeterCodeValidate(mergedMeters)
|
||||||
|
|
|
@ -56,6 +56,8 @@ type EndUserDetail struct {
|
||||||
FinalCharge decimal.NullDecimal `bun:"type:numeric" json:"finalCharge"`
|
FinalCharge decimal.NullDecimal `bun:"type:numeric" json:"finalCharge"`
|
||||||
Initialize bool `bun:"-" json:"-"`
|
Initialize bool `bun:"-" json:"-"`
|
||||||
Origin *Meter04KV `bun:"rel:belongs-to,join:park_id=park_id,join:meter_04kv_id=code" 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)
|
var _ bun.BeforeAppendModelHook = (*EndUserDetail)(nil)
|
||||||
|
@ -110,3 +112,20 @@ type EndUserImport struct {
|
||||||
AdjustFlat decimal.NullDecimal `excel:"adjustFlat"`
|
AdjustFlat decimal.NullDecimal `excel:"adjustFlat"`
|
||||||
AdjustValley decimal.NullDecimal `excel:"adjustValley"`
|
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"`
|
Ratio decimal.Decimal `bun:"type:numeric,notnull" json:"ratio" excel:"ratio"`
|
||||||
Seq int64 `bun:"type:bigint,notnull" json:"seq" excel:"seq"`
|
Seq int64 `bun:"type:bigint,notnull" json:"seq" excel:"seq"`
|
||||||
IsPublicMeter bool `bun:"public_meter,notnull" json:"isPublicMeter" excel:"public"`
|
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"`
|
Enabled bool `bun:",notnull" json:"enabled"`
|
||||||
ParkDetail *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
ParkDetail *Park `bun:"rel:belongs-to,join:park_id=id" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ func NewEmptyDate() Date {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return Date{
|
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
|
}, 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)
|
var _ driver.Valuer = (*Date)(nil)
|
||||||
|
|
||||||
func (d Date) Value() (driver.Value, error) {
|
func (d Date) Value() (driver.Value, error) {
|
||||||
|
|
|
@ -13,7 +13,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
mapset "github.com/deckarep/golang-set/v2"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/shopspring/decimal"
|
"github.com/shopspring/decimal"
|
||||||
"github.com/uptrace/bun"
|
"github.com/uptrace/bun"
|
||||||
|
@ -353,3 +355,112 @@ func (es _EndUserService) BatchImportPVRegister(reportId string, file io.Reader)
|
||||||
cache.AbolishRelation("end_user_detail")
|
cache.AbolishRelation("end_user_detail")
|
||||||
return errs
|
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