enhance(calculate): 完善计算部分

This commit is contained in:
2023-08-07 15:15:11 +08:00
84 changed files with 3173 additions and 5398 deletions

View File

@@ -4,7 +4,17 @@ import (
"electricity_bill_calc/global"
"electricity_bill_calc/logger"
"electricity_bill_calc/model"
"electricity_bill_calc/model/calculate"
"electricity_bill_calc/types"
"encoding/json"
"errors"
"fmt"
"github.com/jackc/pgx/v5"
"github.com/shopspring/decimal"
"golang.org/x/sync/errgroup"
"log"
"strings"
"time"
"github.com/doug-martin/goqu/v9"
_ "github.com/doug-martin/goqu/v9/dialect/postgres"
@@ -68,3 +78,434 @@ func (cr _CalculateRepository) UpdateReportTaskStatus(rid string, status int16,
}
return res.RowsAffected() > 0, nil
}
// 获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的
func (cr _CalculateRepository) GetAllPoolingMeterRelations(pid string, revokedAfter time.Time) ([]model.MeterRelation, error) {
cr.log.Info("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的", zap.String("pid", pid), zap.Time("revokedAfter", revokedAfter))
ctx, cancel := global.TimeoutContext()
defer cancel()
relationsSql, relationsArgs, _ := cr.ds.
From(goqu.T("meter_relations")).
Where(goqu.I("park_id").Eq(pid)).
Where(goqu.Or(
goqu.I("revoked_at").IsNull(),
goqu.I("revoked_at").Gte(revokedAfter),
)).ToSQL()
var meterRelation []model.MeterRelation
err := pgxscan.Select(ctx, global.DB, meterRelation, relationsSql, relationsArgs...)
if err != nil {
cr.log.Error("获取当前园区中所有公摊表计与商户表计之间的关联关系,包括已经解除的出错", zap.Error(err))
return nil, err
}
return meterRelation, nil
}
// 获取当前园区中所有的商户与表计的关联关系,包括已经解除的
func (cr _CalculateRepository) GetAllTenementMeterRelations(pid string, associatedBefore time.Time, disassociatedAfter time.Time) ([]model.TenementMeter, error) {
cr.log.Info("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.String("pid", pid), zap.Time("associatedBefore", associatedBefore), zap.Time("disassociatedAfter", disassociatedAfter))
ctx, cancel := global.TimeoutContext()
defer cancel()
relationsQuerySql, relationsQueryArgs, _ := cr.ds.
From(goqu.T("tenement_meter")).
Where(goqu.I("park_id").Eq(pid)).
Where(goqu.And(
goqu.I("associated_at").IsNull(),
goqu.I("associated_at").Lte(associatedBefore),
)).
Where(goqu.And(
goqu.I("associated_at").IsNull(),
goqu.I("associated_at").Gte(disassociatedAfter),
)).ToSQL()
var tenementMeter []model.TenementMeter
err := pgxscan.Select(ctx, global.DB, tenementMeter, relationsQuerySql, relationsQueryArgs...)
if err != nil {
cr.log.Error("获取当前园区中所有的商户与表计的关联关系,包括已经解除的", zap.Error(err))
return nil, err
}
return tenementMeter, nil
}
// 获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据
func (cr _CalculateRepository) GetMeterReadings(rid string, meterType int16) ([]model.MeterReading, error) {
cr.log.Info("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据", zap.String("rid", rid), zap.Int16("meterType", meterType))
ctx, cancel := global.TimeoutContext()
defer cancel()
readingsQuerySql, readingsQueryArgs, _ := cr.ds.
From(goqu.T("meter_reading").As(goqu.I("mr"))).
Join(
goqu.T("report").As("r"),
goqu.On(goqu.I("r.park_id").Eq(goqu.I("mr.park_id"))),
).
Where(
goqu.I("r.id").Eq(rid),
goqu.I("mr.meter_type").Eq(meterType),
// TODO2023.08.02 此方法出错优先查看是否这里出问题
goqu.I("mr.read_at::date <@ r.period"),
).
Order(goqu.I("mr.read_at").Asc()).Select(goqu.I("mr.*")).ToSQL()
var readings []model.MeterReading
err := pgxscan.Select(ctx, global.DB, readings, readingsQuerySql, readingsQueryArgs...)
if err != nil {
cr.log.Error("获取指定报表中所有涉及到的指定类型表计在核算时间段内的所有读数数据出错", zap.Error(err))
return nil, err
}
return readings, nil
}
// 获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数
func (cr _CalculateRepository) GetLastPeriodReadings(rid string, meterType int16) ([]model.MeterReading, error) {
cr.log.Info("获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数", zap.String("rid", rid), zap.Int16("meterType", meterType))
ctx, cancel := global.TimeoutContext()
defer cancel()
readingsSql, readingsArgs, _ := cr.ds.From(goqu.T("meter_reading").As("mr")).
Select(
goqu.MAX("mr.read_at").As("read_at"),
goqu.I("mr.park_id"),
goqu.I("mr.meter_id"),
goqu.I("mr.meter_type"),
goqu.I("mr.ratio"),
goqu.I("mr.overall"),
goqu.I("mr.critical"),
goqu.I("mr.peak"),
goqu.I("mr.flat"),
goqu.I("mr.valley"),
).
Join(
goqu.T("report").As("r"),
goqu.On(goqu.I("r.park_id").Eq(goqu.I("mr.park_id"))),
).
Where(
goqu.I("r.id").Eq(rid),
goqu.I("mr.meter_type").Eq(meterType),
goqu.I(" mr.read_at::date <= lower(r.period)"),
).
GroupBy(
goqu.I("mr.park_id"),
goqu.I("mr.meter_id"),
goqu.I("mr.meter_type"),
goqu.I("mr.ratio"),
goqu.I("mr.overall"),
goqu.I("mr.critical"),
goqu.I("mr.peak"),
goqu.I("mr.flat"),
goqu.I("mr.valley"),
goqu.I("r.period"),
).ToSQL()
var readings []model.MeterReading
err := pgxscan.Select(ctx, global.DB, readings, readingsSql, readingsArgs...)
if err != nil {
cr.log.Error("获取指定报表中所有涉及到的表计在核算起始日期前的最后一次读数出错", zap.Error(err))
return nil, err
}
return readings, nil
}
// 取得指定报表所涉及的所有商户信息
func (cr _CalculateRepository) GetAllTenements(rid string) ([]model.Tenement, error) {
cr.log.Info("取得指定报表所涉及的所有商户信息", zap.String("rid", rid))
ctx, cancel := global.TimeoutContext()
defer cancel()
tenementQuerySql, tenementQueryArgs, _ := cr.ds.
From(goqu.T("tenement").As("t")).
LeftJoin(
goqu.T("park_building").As("b"),
goqu.On(goqu.I("b.id").Eq(goqu.I("t.building"))),
).
Join(
goqu.T("report").As("r"),
goqu.On(goqu.I("r.park_id").Eq(goqu.I("t.park_id"))),
).
Select(
goqu.I("t.*"),
goqu.I("b.name").As("building_name"),
).
Where(
goqu.I("r.id").Eq(rid),
goqu.I("t.moved_in_at <= upper(r.period)"),
).ToSQL()
var tenements []model.Tenement
err := pgxscan.Select(ctx, global.DB, tenements, tenementQuerySql, tenementQueryArgs...)
if err != nil {
cr.log.Error("取得指定报表所涉及的所有商户信息出错", zap.Error(err))
return nil, err
}
return tenements, nil
}
func (cr _CalculateRepository) ClearReportContent(tx pgx.Tx, rid string) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
querysql, querarg, _ := cr.ds.Delete("report_summary").
Where(goqu.C("report_id").Eq(rid)).ToSQL()
_, err := tx.Exec(ctx, querysql, querarg...)
if err != nil {
return err
}
querysql, querarg, _ = cr.ds.Delete("report_public_consumption").
Where(goqu.C("report_id").Eq(rid)).ToSQL()
_, err = tx.Exec(ctx, querysql, querarg...)
if err != nil {
return err
}
querysql, querarg, _ = cr.ds.Delete("report_pooled_consumption").
Where(goqu.C("report_id").Eq(rid)).ToSQL()
_, err = tx.Exec(ctx, querysql, querarg...)
if err != nil {
return err
}
querysql, querarg, _ = cr.ds.Delete("report_tenement").
Where(goqu.C("report_id").Eq(rid)).ToSQL()
_, err = tx.Exec(ctx, querysql, querarg...)
if err != nil {
return err
}
return nil
}
func (cr _CalculateRepository) SaveReportPublics(tx pgx.Tx, rid string, meters []calculate.Meter) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
if len(meters) == 0 {
// 如果没有公共表计则直接返回
return nil
}
// 准备插入表达式
insertExpr := cr.ds.Insert("report_public_consumption").
Cols(
"report_id", "park_meter_id", "overall", "critical", "peak", "flat", "valley",
"loss_adjust", "consumption_total", "loss_adjust_total", "final_total",
).Prepared(true)
// 添加值到插入表达式中
for _, meter := range meters {
insertExpr = insertExpr.Vals([]interface{}{
rid,
meter.Code,
meter.Overall.Fee,
meter.Critical.Fee,
meter.Peak.Fee,
meter.Flat.Fee,
meter.Valley.Fee,
meter.AdjustLoss.Fee,
meter.Overall.Fee,
meter.AdjustLoss.Fee,
meter.Overall.Fee.Add(meter.AdjustLoss.Fee),
})
}
// 执行插入语句
inserSql, insertArgs, err := insertExpr.Prepared(true).ToSQL()
if err != nil {
return err
}
if _, err := tx.Exec(ctx, inserSql, insertArgs); err != nil {
return fmt.Errorf("保存报表核算概要失败: %w", err)
}
return nil
}
func (cr _CalculateRepository) SaveReportSummary(tx pgx.Tx, summary calculate.Summary) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
// 构建插入表达式
insertsql, insertArgs, _ := cr.ds.Insert("report_summary").
Cols(
"report_id", "overall", "critical", "peak", "flat", "valley",
"loss", "loss_fee", "basic_fee", "basic_pooled_price_consumption", "basic_pooled_price_area",
"adjust_fee", "adjust_pooled_price_consumption", "adjust_pooled_price_area",
"loss_diluted_price", "loss_proportion", "final_diluted_overall",
"consumption_fee", "authorize_loss", "overall_area", "total_consumption",
).
Vals(goqu.Vals{
summary.ReportId, summary.Overall, summary.Critical, summary.Peak, summary.Flat,
summary.Valley, summary.Loss, summary.LossFee, summary.BasicFee,
summary.BasicPooledPriceConsumption, summary.BasicPooledPriceArea,
summary.AdjustFee, summary.AdjustPooledPriceConsumption, summary.AdjustPooledPriceArea,
summary.LossDilutedPrice, summary.LossProportion, summary.FinalDilutedOverall,
summary.ConsumptionFee, summary.AuthoizeLoss, summary.OverallArea, summary.TotalConsumption,
}).Prepared(true).ToSQL()
// 执行插入语句
if _, err := tx.Exec(ctx, insertsql, insertArgs...); err != nil {
cr.log.Error("保存报表核算概要失败。")
return err
}
return nil
}
type NestedMeter struct {
Overall model.ConsumptionUnit
Critical model.ConsumptionUnit
Peak model.ConsumptionUnit
Flat model.ConsumptionUnit
Valley model.ConsumptionUnit
CoveredArea decimal.Decimal
// Add other fields here as needed
}
func (cr _CalculateRepository) SaveReportPoolings(tx pgx.Tx,
rid string,
meters []calculate.Meter,
relations []model.MeterRelation,
tenements []calculate.Meter) error {
ctx, cancel := global.TimeoutContext()
defer cancel()
if len(meters) == 0 {
return nil
}
relationsSlaves := make(map[string]bool)
for _, r := range relations {
relationsSlaves[r.SlaveMeter] = true
}
tenementCodes := make(map[string]bool)
for _, t := range tenements {
tenementCodes[t.Code] = true
}
for _, r := range relations {
if _, ok := tenementCodes[r.SlaveMeter]; !ok {
return errors.New("unknown tenement meter in active meter relations")
}
}
var insertQueries []goqu.InsertDataset
for _, meter := range meters {
submeters := make([]NestedMeter, 0)
for _, r := range relations {
if r.MasterMeter == meter.Code {
for _, t := range tenements {
if t.Code == r.SlaveMeter {
submeters = append(submeters, NestedMeter{
Overall: t.Overall,
Critical: t.Critical,
Peak: t.Peak,
Flat: t.Flat,
Valley: t.Valley,
})
}
}
}
}
submetersJSON, err := json.Marshal(submeters)
if err != nil {
return err
}
insertQuery := goqu.Insert("report_pooled_consumption").
Cols("report_id", "pooled_meter_id", "overall", "critical", "peak", "flat", "valley", "pooled_area", "diluted").
Vals(goqu.Vals{rid, meter.Code, meter.Overall, meter.Critical, meter.Peak, meter.Flat, meter.Valley, meter.CoveredArea, submetersJSON})
insertQueries = append(insertQueries, *insertQuery)
}
eg, _ := errgroup.WithContext(ctx)
for _, insertQuery := range insertQueries {
insertQuery := insertQuery // Capture loop variable
eg.Go(func() error {
sql, args, err := insertQuery.ToSQL()
if err != nil {
return err
}
_, err = tx.Exec(ctx, sql, args...)
return err
})
}
return eg.Wait()
}
func (cr _CalculateRepository) SaveReportTenement(tx pgx.Tx, report model.ReportIndex, tenements []model.Tenement, tenementCharges []calculate.TenementCharge) error {
if len(tenements) == 0 {
// 如果没有商户则直接返回
return nil
}
cr.log.Info("保存商户报表。")
ctx, cancel := global.TimeoutContext()
defer cancel()
insertQuery := cr.ds.Insert("report_tenement").Prepared(true)
values := []goqu.Record{}
for _, tenement := range tenements {
charge := findTenementCharge(tenementCharges, tenement.Id)
values = append(values, goqu.Record{
"report_id": report.Id,
"tenement_id": tenement.Id,
"tenement_detail": toJSONString(tenement),
"calc_period": report.Period,
"overall": toJSONString(charge.Overall),
"critical": toJSONString(charge.Critical),
"peak": toJSONString(charge.Peak),
"flat": toJSONString(charge.Flat),
"valley": toJSONString(charge.Valley),
"loss": toJSONString(charge.Loss),
"basic_fee_pooled": charge.BasicFee,
"adjust_fee_pooled": charge.AdjustFee,
"loss_fee_pooled": charge.LossPooled,
"final_pooled": charge.PublicPooled,
"final_charge": charge.FinalCharges,
"meters": toJSONString(convertToNestedMeters(charge.Submeters)),
"pooled": toJSONString(convertToNestedMeters(charge.Poolings)),
})
}
sql, params, err := insertQuery.Rows(values).Prepared(true).ToSQL()
if err != nil {
log.Println("sql出现问题................................")
return err
}
tx.Exec(ctx, sql, params...)
if err != nil {
return err
}
return nil
}
// findTenementCharge 在 TenementCharges 切片中查找指定商户的核算内容
func findTenementCharge(charges []calculate.TenementCharge, tenementID string) calculate.TenementCharge {
for _, charge := range charges {
if charge.Tenement == tenementID {
return charge
}
}
return calculate.TenementCharge{}
}
// convertToNestedMeters 将 Meter 切片转换为 NestedMeter 切片
func convertToNestedMeters(meters []*calculate.Meter) []NestedMeter {
nestedMeters := []NestedMeter{}
for _, meter := range meters {
nestedMeters = append(nestedMeters, NestedMeter{
Overall: meter.Overall,
Critical: meter.Critical,
Peak: meter.Peak,
Flat: meter.Flat,
Valley: meter.Valley,
CoveredArea: meter.CoveredArea,
})
}
return nestedMeters
}
// toJSONString 将对象转换为 JSON 字符串
func toJSONString(obj interface{}) string {
return `"` + strings.ReplaceAll(fmt.Sprintf("%#v", obj), `"`, `\"`) + `"`
}

449
repository/god_mode.go Normal file
View File

@@ -0,0 +1,449 @@
package repository
import (
"context"
"electricity_bill_calc/global"
"electricity_bill_calc/logger"
"fmt"
"github.com/doug-martin/goqu/v9"
"github.com/georgysavva/scany/v2/pgxscan"
"github.com/jackc/pgx/v5"
"go.uber.org/zap"
)
type _GMRepository struct {
log *zap.Logger
ds goqu.DialectWrapper
}
var GMRepository = &_GMRepository{
log: logger.Named("Repository", "GM"),
ds: goqu.Dialect("postgres"),
}
func (gm _GMRepository) DeleteMeterBinding(ctx context.Context, tx pgx.Tx, pid string, tenements []string, meterCodes ...[]string) error {
DeleteQuery := gm.ds.From(goqu.T("tenement_meter")).
Where(goqu.I("park_id").Eq(pid)).
Delete()
if len(tenements) > 0 {
DeleteQuery = DeleteQuery.
Where(goqu.I("tenement_id").In(tenements))
}
if len(meterCodes) > 0 {
DeleteQuery = DeleteQuery.
Where(goqu.I("meter_id").In(meterCodes))
}
DeleteQuerySql, DeleteQueryArgs, _ := DeleteQuery.ToSQL()
_, err := tx.Exec(ctx, DeleteQuerySql, DeleteQueryArgs...)
if err != nil {
gm.log.Error("数据库在删除tenement_meter表数据中出错", zap.Error(err))
tx.Rollback(ctx)
return err
}
return nil
}
func (gm _GMRepository) DeleteTenements(ctx context.Context, tx pgx.Tx, pid string, tenements ...[]string) error {
DeleteTenements := gm.ds.
From("tenement").
Where(goqu.I("park_id").Eq(pid)).
Delete()
fmt.Println(len(tenements))
if len(tenements) > 0 {
DeleteTenements = DeleteTenements.
Where(goqu.I("id").In(tenements))
}
DeleteTenementsSql, DeleteTenementsArgs, _ := DeleteTenements.ToSQL()
_, err := tx.Exec(ctx, DeleteTenementsSql, DeleteTenementsArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("删除商户信息出错", zap.Error(err))
return err
}
return nil
}
func (gm _GMRepository) DeleteInvoices(ctx context.Context, tx pgx.Tx, parks string, val ...[]string) error {
if len(val) > 0 {
updateQuery, updateQueryArgs, _ := gm.ds.
Update(goqu.T("report_tenement")).
Set(goqu.Record{"invoice": nil}).
Where(goqu.I("invoice").In(val)).
Where(
goqu.I("report_id").
Eq(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
),
).ToSQL()
_, err := tx.Exec(ctx, updateQuery, updateQueryArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("更新发票记录出错", zap.Error(err))
return err
}
} else {
updateQuery, updateQueryArgs, _ := gm.ds.
Update(goqu.T("report_tenement")).
Set(goqu.Record{"invoice": nil}).
Where(
goqu.I("report_id").
Eq(gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err := tx.Exec(ctx, updateQuery, updateQueryArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("更新发票记录出错", zap.Error(err))
return err
}
}
deleteQuery := gm.ds.
From(goqu.T("invoices")).
Where(goqu.I("park_id").Eq(parks)).
Delete()
if len(val) > 0 {
deleteQuery.Where(goqu.I("invoice_code").In(val))
}
deleteQuerySql, deleteQueryArgs, _ := deleteQuery.ToSQL()
_, err := tx.Exec(ctx, deleteQuerySql, deleteQueryArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("删除指定园区发票记录出错", zap.Error(err))
return err
}
return nil
}
func (gm _GMRepository) DeleteMeterPoolings(ctx context.Context, tx pgx.Tx, parks string, val ...[]string) error {
deleteQuery := gm.ds.
Delete(goqu.T("meter_relations")).
Where(goqu.I("park_id").Eq(parks))
if len(val) > 0 {
deleteQuery = deleteQuery.
Where(
goqu.I("master_meter_id").In(val),
goqu.Or(goqu.I("slave_meter_id").In(val)),
)
}
deleteQuerySql, deleteQueryArgs, _ := deleteQuery.ToSQL()
_, err := tx.Exec(ctx, deleteQuerySql, deleteQueryArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("删除指定园区中的表计分摊关系失败", zap.Error(err))
return err
}
return nil
}
func (gm _GMRepository) DeleteMeters(ctx context.Context, tx pgx.Tx, parks string, val ...[]string) error {
deleteQuery := gm.ds.
Delete(goqu.T("meter_04kv")).
Where(goqu.I("park_id").Eq(parks))
if len(val) > 0 {
deleteQuery = deleteQuery.Where(goqu.I("code").In(val))
}
deleteQuerySql, deleteQueryArgs, _ := deleteQuery.ToSQL()
_, err := tx.Exec(ctx, deleteQuerySql, deleteQueryArgs...)
if err != nil {
tx.Rollback(ctx)
gm.log.Error("删除指定园区的符合条件的标记出错", zap.Error(err))
return err
}
return nil
}
func (gm _GMRepository) DeleteReports(ctx context.Context, tx pgx.Tx, parks string, val ...[]string) error {
var err error
if len(val) > 0 {
deleteReportTenementQuerySql, deleteReportTenementQueryArgs, _ := gm.ds.
Delete(goqu.T("report_tenement")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportTenementQuerySql, deleteReportTenementQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportPooledConsumptionQuerySql, deleteReportPooledConsumptionQueryArgs, _ := gm.ds.
Delete(goqu.T("report_pooled_consumption")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportPooledConsumptionQuerySql, deleteReportPooledConsumptionQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportPublicConsumptionQuerySql, deleteReportPublicConsumptionQueryArgs, _ := gm.ds.
Delete(goqu.T("report_public_consumption")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportPublicConsumptionQuerySql, deleteReportPublicConsumptionQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportSummaryQuerySql, deleteReportSummaryQueryArgs, _ := gm.ds.
Delete(goqu.T("report_summary")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportSummaryQuerySql, deleteReportSummaryQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportTaskQuerySql, deleteReportTaskQueryArgs, _ := gm.ds.
Delete(goqu.T("report_task")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportTaskQuerySql, deleteReportTaskQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportQuerySql, deleteReportQueryArgs, _ := gm.ds.
Delete(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)).ToSQL()
_, err = tx.Exec(ctx, deleteReportQuerySql, deleteReportQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
} else {
deleteReportTenementQuerySql, deleteReportTenementQueryArgs, _ := gm.ds.
Delete(goqu.T("report_tenement")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportTenementQuerySql, deleteReportTenementQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportPooledConsumptionQuerySql, deleteReportPooledConsumptionQueryArgs, _ := gm.ds.
Delete(goqu.T("report_pooled_consumption")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportPooledConsumptionQuerySql, deleteReportPooledConsumptionQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportPublicConsumptionQuerySql, deleteReportPublicConsumptionQueryArgs, _ := gm.ds.
Delete(goqu.T("report_public_consumption")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportPublicConsumptionQuerySql, deleteReportPublicConsumptionQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportSummaryQuerySql, deleteReportSummaryQueryArgs, _ := gm.ds.
Delete(goqu.T("report_summary")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportSummaryQuerySql, deleteReportSummaryQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportTaskQuerySql, deleteReportTaskQueryArgs, _ := gm.ds.
Delete(goqu.T("report_task")).
Where(goqu.I("report_id").In(
gm.ds.
From(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)),
)).ToSQL()
_, err = tx.Exec(ctx, deleteReportTaskQuerySql, deleteReportTaskQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
deleteReportQuerySql, deleteReportQueryArgs, _ := gm.ds.
Delete(goqu.T("report")).
Where(goqu.I("park_id").Eq(parks)).ToSQL()
_, err = tx.Exec(ctx, deleteReportQuerySql, deleteReportQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
}
return nil
}
func (gm _GMRepository) DeleteBuildings(ctx context.Context, tx pgx.Tx, parks string, val ...[]string) error {
if len(val) > 0 {
updateBulidingSql, updateBlidingArgs, _ := gm.ds.
Update(goqu.T("tenement")).
Set(goqu.Record{"building": nil}).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("building").In(
gm.ds.
From(goqu.I("park_building")).
Where(goqu.I("park_id").Eq(parks)).
Where(goqu.I("id").In(val)).
Select(goqu.I("id")),
)).ToSQL()
_, err := tx.Exec(ctx, updateBulidingSql, updateBlidingArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
} else {
updateBulidingSql, updateBlidingArgs, _ := gm.ds.
Update(goqu.T("tenement")).
Set(goqu.Record{"building": nil}).
Where(goqu.I("park_id").Eq(parks)).ToSQL()
_, err := tx.Exec(ctx, updateBulidingSql, updateBlidingArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
}
deleteQuery := gm.ds.
Delete(goqu.I("park_building")).
Where(goqu.I("park_id").Eq(parks))
if len(val) > 0 {
deleteQuery = deleteQuery.
Where(goqu.I("id").In(val))
}
deleteQuerySql, deleteQueryArgs, _ := deleteQuery.ToSQL()
_, err := tx.Exec(ctx, deleteQuerySql, deleteQueryArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
return nil
}
func (gm _GMRepository) DeleteParks(ctx context.Context, tx pgx.Tx, park []string) error {
deleteParksSql, deleteParksArgs, _ := gm.ds.
Delete(goqu.T("park")).
Where(goqu.I("id").In(park)).ToSQL()
_, err := tx.Exec(ctx, deleteParksSql, deleteParksArgs...)
if err != nil {
tx.Rollback(ctx)
return err
}
return nil
}
func (gm _GMRepository) ListAllParkIdsInUser(ctx context.Context, tx pgx.Tx, uid string) ([]string, error) {
SearchParkIdsSql, SearchParkIdsArgs, _ := gm.ds.
From(goqu.T("park")).
Where(goqu.I("user_id").Eq(uid)).
Select(goqu.I("id")).ToSQL()
var pids []string
err := pgxscan.Select(ctx, global.DB, &pids, SearchParkIdsSql, SearchParkIdsArgs...)
if err != nil {
gm.log.Error("查询["+uid+"]用户下的所有园区失败", zap.Error(err))
tx.Rollback(ctx)
return nil, err
}
return pids, nil
}
func (gm _GMRepository) DeleteUsers(ctx context.Context, tx pgx.Tx, uid string) error {
var err error
//删除用户关联
DeleteUserChargeSql, DeleteUserChargeArgs, _ := gm.ds.
Delete(goqu.T("user_charge")).
Where(goqu.I("id").Eq(uid)).ToSQL()
_, err = tx.Exec(ctx,DeleteUserChargeSql,DeleteUserChargeArgs...)
if err != nil {
gm.log.Error("user_charge表关联出错",zap.Error(err))
tx.Rollback(ctx)
return err
}
//删除用户详细信息
DeleteUserDetailSql, DeleteUserDetailArgs,_ := gm.ds.
Delete(goqu.T("user_detail")).
Where(goqu.I("id").Eq(uid)).ToSQL()
_, err = tx.Exec(ctx,DeleteUserDetailSql,DeleteUserDetailArgs...)
if err != nil {
gm.log.Error("user_detail表详细信息出错",zap.Error(err))
tx.Rollback(ctx)
return err
}
//删除用户基础信息
DeleteUserSql, DeleteUserArgs,_ := gm.ds.
Delete(goqu.T("users")).
Where(goqu.I("id").Eq(uid)).ToSQL()
_, err = tx.Exec(ctx,DeleteUserSql,DeleteUserArgs...)
if err != nil {
gm.log.Error("user表基础信息出错",zap.Error(err))
tx.Rollback(ctx)
return err
}
return nil
}

View File

@@ -678,7 +678,7 @@ func (rr _ReportRepository) IsLastReport(rid string) (bool, error) {
defer cancel()
checkSql, checkArgs, _ := rr.ds.
From(goqu.T("report")).
From(goqu.T("report").As("r")).
Select(goqu.COUNT("*")).
Where(
goqu.I("r.id").Eq(rid),

242
repository/withdraw.go Normal file
View File

@@ -0,0 +1,242 @@
package repository
import (
"electricity_bill_calc/config"
"electricity_bill_calc/global"
"electricity_bill_calc/logger"
"electricity_bill_calc/model"
"electricity_bill_calc/tools"
"electricity_bill_calc/types"
"fmt"
"github.com/doug-martin/goqu/v9"
"github.com/georgysavva/scany/v2/pgxscan"
"go.uber.org/zap"
)
type _WithdrawRepository struct {
log *zap.Logger
ds goqu.DialectWrapper
}
var WithdrawRepository = &_WithdrawRepository{
log: logger.Named("Repository", "Withdraw"),
ds: goqu.Dialect("postgres"),
}
//该方法用于分页查询核算报表
func (wd _WithdrawRepository) FindWithdraw(page uint, keyword *string) ([]model.Withdraw, int64, error) {
wd.log.Info("查询核算报表", zap.Stringp("keyword", keyword), zap.Int("page", int(page)))
ctx, cancel := global.TimeoutContext()
defer cancel()
/**
如果访问数据库次数过多出现时间过长的话可以用这个尝试优化未测试的sql语句
wd.ds.From(goqu.T("report")).
Where(goqu.I("withdraw").Eq(1)).
Select(
goqu.I("report.*"),
goqu.I("park.*"),
goqu.I("user_detail.*"),
).
Join(
goqu.T("park"), goqu.On(goqu.I("report.park_id").Eq(goqu.I("park.id"))),
).
Join(
goqu.T("user_detail"), goqu.On(goqu.I("park.user_id").Eq(goqu.I("user_detail.id"))),
).ToSQL()
SELECT report.*, park.*, user_detail.*
FROM report as r
JOIN park as p ON r.park_id = p.id
JOIN user_detail as ud ON p.user_id = ud.id
WHERE withdraw = 1
AND p.name Like '%keyword%'
AND ud.name Like '%keyword%'
*/
reportQuery := wd.ds.
From(goqu.T("report").As("r")).
Where(goqu.I("withdraw").Eq(1)).
Join(goqu.T("park").As("p"), goqu.On(goqu.I("r.park_id").Eq(goqu.I("p.id")))).
Join(goqu.T("user_detail").As("ud"), goqu.On(goqu.I("p.user_id").Eq(goqu.I("ud.id")))).
Where(goqu.I("p.deleted_at").IsNull()).
Where(goqu.I("ud.deleted_at").IsNull()).
Select(
goqu.I("r.id").As("report_id"), goqu.I("r.last_withdraw_applied_at"), goqu.I("r.last_withdraw_audit_at"),
goqu.I("r.park_id").As("report_park_id"), goqu.I("r.period"), goqu.I("r.published"), goqu.I("r.published_at"), goqu.I("r.withdraw"),
goqu.I("p.address").As("park_address"), goqu.I("p.area"), goqu.I("p.capacity"), goqu.I("p.category"), goqu.I("p.contact").As("park_contact"),
goqu.I("p.id").As("park_id"), goqu.I("p.meter_04kv_type"), goqu.I("p.name").As("park_name"), goqu.I("p.phone").As("park_phone"), goqu.I("p.region").As("park_region"),
goqu.I("p.tenement_quantity"), goqu.I("p.user_id"), goqu.I("ud.address"), goqu.I("ud.contact").As("user_detail_contact"),
goqu.I("ud.id").As("ud_id"), goqu.I("ud.name").As("user_detail_name"), goqu.I("ud.phone").As("user_detail_phone"), goqu.I("ud.region").As("user_detail_region"),
)
countReportQuery := wd.ds.
From(goqu.T("report").As("r")).
Where(goqu.I("withdraw").Eq(1)).
Join(goqu.T("park").As("p"), goqu.On(goqu.I("r.park_id").Eq(goqu.I("p.id")))).
Join(goqu.T("user_detail").As("ud"), goqu.On(goqu.I("p.user_id").Eq(goqu.I("ud.id")))).
Select(goqu.COUNT("*"))
if keyword != nil && len(*keyword) > 0 {
pattern := fmt.Sprintf("%%%s%%", *keyword)
reportQuery = reportQuery.Where(goqu.Or(
goqu.I("p.name").ILike(pattern),
goqu.I("ud.name").ILike(pattern),
))
}
reportQuery = reportQuery.Order(goqu.I("r.created_at").Desc())
currentPostion := (page - 1) * config.ServiceSettings.ItemsPageSize
reportQuery = reportQuery.Offset(currentPostion).Limit(config.ServiceSettings.ItemsPageSize)
reportSql, reportArgs, _ := reportQuery.Prepared(true).ToSQL()
countReportQuerySql, countReportQueryArgs, _ := countReportQuery.Prepared(true).ToSQL()
var (
reports []*model.ReportRes = make([]*model.ReportRes, 0)
total int64
)
var err error
err = pgxscan.Select(ctx, global.DB, &reports, reportSql, reportArgs...)
if err != nil {
fmt.Println(err)
wd.log.Error("查询报表记录失败。", zap.Error(err))
return make([]model.Withdraw, 0), 0, err
}
if err = pgxscan.Get(ctx, global.DB, &total, countReportQuerySql, countReportQueryArgs...); err != nil {
wd.log.Error("查询报表记录总数失败。", zap.Error(err))
return make([]model.Withdraw, 0), 0, err
}
if len(reports) <= 0 {
return make([]model.Withdraw, 0), total, nil
}
var withdrawReses []model.Withdraw
//TODO: 2023.07.24对查询到的数据进行拼接(完成)
for _, v := range reports {
Begin := v.Period.SafeLower().Format("2006-01-02")
End := v.Period.SafeUpper().Format("2006-01-02")
var withdrawRes model.Withdraw
report := model.SimplifiedReport{
ID: v.ReportId,
LastWithdrawAppliedAt: tools.TimeToStringPtr(v.LastWithdrawAppliedAt),
LastWithdrawAuditAt: tools.TimeToStringPtr(v.LastWithdrawAuditAt),
Message: nil,
ParkID: v.ParkID,
PeriodBegin: Begin,
PeriodEnd: End,
Published: v.Published,
PublishedAt: tools.TimeToStringPtr(v.LastWithdrawAuditAt),
Status: 0.,
Withdraw: v.Withdraw,
}
park := model.SimplifiedPark{
Address: v.ParkAddress,
Area: tools.NullDecimalToString(v.Area),
Capacity: tools.NullDecimalToString(v.Capacity),
Category: int16(v.Category),
Contact: v.ParkContact,
ID: v.ParkId,
Meter04KvType: v.Meter04KVType,
Name: v.ParkName,
Phone: v.ParkPhone,
Region: &v.ParkRegion,
Tenement: tools.NullDecimalToString(v.TenementQuantity),
UserID: v.UserID,
}
userInfo := model.UserInfos{
Address: v.Address,
Contact: &v.Contact,
ID: v.ID,
Name: v.Name,
Phone: &v.Phone,
Region: v.Region,
}
withdrawRes.Report = report
withdrawRes.Park = park
withdrawRes.User = userInfo
withdrawReses = append(withdrawReses, withdrawRes)
}
return withdrawReses, total, nil
}
//该方法用于审核同意报表撤回
func (wd _WithdrawRepository) ReviewTrueReportWithdraw( rid string) (bool, error) {
wd.log.Info("审核指定的报表", zap.String("rid", rid))
ctx, cancel := global.TimeoutContext()
defer cancel()
//update report set withdraw=$2,
//last_withdraw_audit_at=$3, published=false,
//published_at=null where id=$1
tx, err := global.DB.Begin(ctx)
if err != nil {
wd.log.Error("开启数据库事务失败", zap.Error(err))
}
updateQuerySql, updateArgs, _ := wd.ds.
Update(goqu.T("report")).
Set(goqu.Record{
"withdraw": model.REPORT_WITHDRAW_GRANTED,
"last_withdraw_audit_at": types.Now(),
"published": false,
"published_at": nil,
}).
Where(goqu.I("id").Eq(rid)).
Prepared(true).ToSQL()
rs, err := tx.Exec(ctx, updateQuerySql, updateArgs...)
if err != nil {
wd.log.Error("审核报表失败", zap.Error(err))
return false, err
}
err = tx.Commit(ctx)
if err != nil {
wd.log.Error("提交数据库事务失败", zap.Error(err))
return false, err
}
return rs.RowsAffected() > 0, nil
}
//该方法用于审核拒绝报表撤回
func (wd _WithdrawRepository) ReviewFalseReportWithdraw( rid string) (bool, error) {
wd.log.Info("审核指定的报表", zap.String("rid", rid))
ctx, cancel := global.TimeoutContext()
defer cancel()
tx, err := global.DB.Begin(ctx)
if err != nil {
wd.log.Error("开启数据库事务失败", zap.Error(err))
}
updateQuerySql, updateArgs, _ := wd.ds.
Update(goqu.T("report")).
Set(goqu.Record{
"withdraw": model.REPORT_WITHDRAW_DENIED,
"last_withdraw_audit_at": types.Now(),
"published": false,
"published_at": nil,
}).
Where(goqu.I("id").Eq(rid)).
Prepared(true).ToSQL()
rs, err := tx.Exec(ctx, updateQuerySql, updateArgs...)
if err != nil {
wd.log.Error("审核报表失败", zap.Error(err))
return false, err
}
err = tx.Commit(ctx)
if err != nil {
wd.log.Error("提交数据库事务失败", zap.Error(err))
return false, err
}
return rs.RowsAffected() > 0, nil
}