electricity_bill_calc_service/service/god_mode.go

799 lines
19 KiB
Go

package service
import (
"electricity_bill_calc/cache"
"electricity_bill_calc/exceptions"
"electricity_bill_calc/global"
"electricity_bill_calc/model"
"fmt"
"time"
"github.com/samber/lo"
"github.com/shopspring/decimal"
"xorm.io/builder"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
type _GodModeService struct{}
var GodModeService _GodModeService
// 从此处开始为删除报表相关的部分
func (_GodModeService) resetReportIndex(tx *xorm.Session, reportId string) (bool, error) {
var report = new(model.Report)
has, err := tx.ID(reportId).NoAutoCondition().Get(report)
if err != nil {
tx.Rollback()
return false, err
}
if !has {
tx.Rollback()
return false, exceptions.NewNotFoundError("指定报表索引未找到。")
}
report.StepState.Summary = false
report.StepState.WillDiluted = false
report.StepState.Submeter = false
report.StepState.Calculate = false
report.StepState.Preview = false
report.StepState.Publish = false
report.Published = false
report.PublishedAt = nil
report.Withdraw = model.REPORT_NOT_WITHDRAW
report.LastWithdrawAppliedAt = nil
report.LastWithdrawAuditAt = nil
affected, err := tx.
ID(reportId).
MustCols(
"step_state",
"published",
"published_at",
"withdraw",
"last_withdraw_applied_at",
"last_withdraw_audit_at",
).
Update(report)
if err != nil {
tx.Rollback()
return false, err
}
return affected > 0, err
}
func (_GodModeService) resetReportSummary(tx *xorm.Session, reportId string) (bool, error) {
var summary = &model.ReportSummary{
ReportId: reportId,
}
_, err := tx.ID(reportId).AllCols().NoAutoCondition().Update(summary)
if err != nil {
tx.Rollback()
return false, err
}
var report = new(model.Report)
_, err = tx.ID(reportId).NoAutoCondition().Unscoped().Get(report)
if err != nil {
tx.Rollback()
return false, err
}
report.StepState.Summary = false
rows, err := tx.ID(reportId).Cols("step_state").NoAutoCondition().Update(report)
if err != nil {
tx.Rollback()
}
return rows >= 0, err
}
func (_GodModeService) flushReportMaintenances(tx *xorm.Session, reportId string) (bool, error) {
_, err := tx.
Where(builder.Eq{"report_id": reportId}).
NoAutoCondition().
Delete(new(model.WillDilutedFee))
if err != nil {
tx.Rollback()
return false, err
}
var report = new(model.Report)
_, err = tx.ID(reportId).NoAutoCondition().Unscoped().Get(report)
if err != nil {
tx.Rollback()
return false, err
}
report.StepState.WillDiluted = false
rows, err := tx.ID(reportId).Cols("step_state").NoAutoCondition().Update(report)
if err != nil {
tx.Rollback()
}
return rows >= 0, err
}
func (_GodModeService) resetSingleEndUserRecord(tx *xorm.Session, record *model.EndUserDetail, additionalColumns ...string) (bool, error) {
record.CurrentPeriodOverall = decimal.Zero
record.CurrentPeriodCritical = decimal.Zero
record.CurrentPeriodPeak = decimal.Zero
record.CurrentPeriodFlat = decimal.Zero
record.CurrentPeriodValley = decimal.Zero
record.AdjustOverall = decimal.Zero
record.AdjustCritical = decimal.Zero
record.AdjustPeak = decimal.Zero
record.AdjustFlat = decimal.Zero
record.AdjustValley = decimal.Zero
record.Overall.Valid = false
record.OverallFee.Valid = false
record.OverallProportion = decimal.Zero
record.Critical.Valid = false
record.CriticalFee.Valid = false
record.Peak.Valid = false
record.PeakFee.Valid = false
record.Flat.Valid = false
record.FlatFee.Valid = false
record.Valley.Valid = false
record.ValleyFee.Valid = false
record.BasicFeeDiluted.Valid = false
record.AdjustFeeDiluted.Valid = false
record.LossDiluted.Valid = false
record.LossFeeDiluted.Valid = false
record.MaintenanceFeeDiluted.Valid = false
record.FinalDiluted.Valid = false
record.PublicConsumptionDiluted.Valid = false
record.FinalCharge.Valid = false
columns := []string{
"current_period_overall",
"current_period_critical",
"current_period_peak",
"current_period_flat",
"current_period_valley",
"adjust_overall",
"adjust_critical",
"adjust_peak",
"adjust_flat",
"adjust_valley",
"overall",
"overall_fee",
"overall_proportion",
"critical",
"critical_fee",
"peak",
"peak_fee",
"flat",
"flat_fee",
"valley",
"valley_fee",
"baseic_fee_diluted",
"adjust_fee_diluted",
"loss_diluted",
"loss_fee_diluted",
"maintenance_fee_diluted",
"public_consumption_diluted",
"final_diluted",
"final_charge",
}
columns = append(columns, additionalColumns...)
affected, err := tx.
ID(schemas.PK{record.ReportId, record.ParkId, record.MeterId}).
MustCols(columns...).
Update(record)
if err != nil || affected == 0 {
tx.Rollback()
return false, err
}
return true, nil
}
func (g _GodModeService) resynchronizeEndUserArchives(tx *xorm.Session, reportId string) (bool, error) {
var currentRecords = make([]*model.EndUserDetail, 0)
err := tx.Where(builder.Eq{"report_id": reportId}).Find(&currentRecords)
if err != nil {
tx.Rollback()
return false, err
}
var report = new(model.Report)
has, err := tx.ID(reportId).NoAutoCondition().Unscoped().Get(report)
if err != nil || !has {
tx.Rollback()
return false, err
}
var latestArchives = make([]model.Meter04KV, 0)
err = tx.Table(new(model.Meter04KV)).Where(builder.Eq{"park_id": report.ParkId}).Find(&latestArchives)
if err != nil {
tx.Rollback()
return false, err
}
for _, meter := range latestArchives {
record, has := lo.Find(currentRecords, func(rec *model.EndUserDetail) bool {
return rec.ParkId == meter.ParkId && rec.MeterId == meter.Code
})
if has {
record.CustomerName = meter.CustomerName
record.Address = meter.Address
record.Ratio = meter.Ratio
record.ContactName = meter.ContactName
record.ContactPhone = meter.ContactPhone
record.Seq = meter.Seq
record.IsPublicMeter = meter.IsPublicMeter
record.WillDilute = meter.WillDilute
success, err := g.resetSingleEndUserRecord(
tx, record,
"customer_name",
"address",
"ratio",
"contact_name",
"contact_phone",
"seq",
"public_meter",
"dilute",
)
if err != nil {
return success, err
}
} else {
newEndUser := model.EndUserDetail{
ReportId: report.Id,
ParkId: report.ParkId,
MeterId: meter.Code,
Seq: meter.Seq,
Ratio: meter.Ratio,
Address: meter.Address,
CustomerName: meter.CustomerName,
ContactName: meter.ContactName,
ContactPhone: meter.ContactPhone,
IsPublicMeter: meter.IsPublicMeter,
WillDilute: meter.WillDilute,
LastPeriodOverall: decimal.Zero,
LastPeriodCritical: decimal.Zero,
LastPeriodPeak: decimal.Zero,
LastPeriodFlat: decimal.Zero,
LastPeriodValley: decimal.Zero,
}
_, err = tx.Insert(newEndUser)
if err != nil {
tx.Rollback()
return false, err
}
}
}
report.StepState.Submeter = false
rows, err := tx.ID(reportId).Cols("step_state").NoAutoCondition().Update(report)
if err != nil {
tx.Rollback()
}
return rows >= 0, nil
}
func (g _GodModeService) resetEndUserRecords(tx *xorm.Session, reportId string) (bool, error) {
var records = make([]*model.EndUserDetail, 0)
err := tx.Where(builder.Eq{"report_id": reportId}).Find(&records)
if err != nil {
tx.Rollback()
return false, err
}
for _, u := range records {
success, err := g.resetSingleEndUserRecord(tx, u)
if err != nil {
return success, err
}
}
var report = new(model.Report)
_, err = tx.ID(reportId).NoAutoCondition().Unscoped().Get(report)
if err != nil {
tx.Rollback()
return false, err
}
report.StepState.Submeter = false
rows, err := tx.ID(reportId).Cols("step_state").NoAutoCondition().Update(report)
if err != nil {
tx.Rollback()
}
return rows >= 0, nil
}
type ReportPeriod struct {
Id string
Period time.Time
}
func (_GodModeService) isTheLatestReport(reportId string) (bool, error) {
var report = new(model.Report)
has, err := global.DBConn.ID(reportId).NoAutoCondition().Get(report)
if err != nil {
return false, err
}
if !has {
return false, exceptions.NewNotFoundError("指定报表索引未找到。")
}
var reports = make([]ReportPeriod, 0)
err = global.DBConn.
Table(new(model.Report)).
Where(builder.Eq{"park_id": report.ParkId}).
Find(&reports)
if err != nil {
return false, err
}
maxReport := lo.MaxBy(reports, func(a, b ReportPeriod) bool {
return a.Period.After(b.Period)
})
return maxReport.Id == reportId, nil
}
func (_GodModeService) forceDeleteReport(tx *xorm.Session, reportId string) (bool, error) {
_, err := tx.Exec("delete from end_user_detail where report_id=?", reportId)
if err != nil {
tx.Rollback()
return false, err
}
_, err = tx.Exec("delete from will_diluted_fee where report_id=?", reportId)
if err != nil {
tx.Rollback()
return false, err
}
_, err = tx.Exec("delete from report_summary where report_id=?", reportId)
if err != nil {
tx.Rollback()
return false, err
}
_, err = tx.Exec("delete from report where id=?", reportId)
if err != nil {
tx.Rollback()
return false, err
}
return true, nil
}
func (g _GodModeService) ClearReportSummary(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.resetReportSummary(tx, reportId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
func (g _GodModeService) ClearReportMaintenances(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.flushReportMaintenances(tx, reportId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
func (g _GodModeService) ResynchronizeEndUser(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.resynchronizeEndUserArchives(tx, reportId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("end_user_detail")
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
func (g _GodModeService) ResetEndUserRegisterRecords(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.resetEndUserRecords(tx, reportId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("end_user_detail")
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
func (g _GodModeService) ResetReport(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能操作非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
var result = true
r, err := g.resetEndUserRecords(tx, reportId)
if err != nil {
return false, err
}
result = result && r
r, err = g.flushReportMaintenances(tx, reportId)
if err != nil {
return false, err
}
result = result && r
r, err = g.resetReportSummary(tx, reportId)
if err != nil {
return false, err
}
result = result && r
r, err = g.resetReportIndex(tx, reportId)
if err != nil {
return false, err
}
result = result && r
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("end_user_detail")
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
func (g _GodModeService) DeleteReport(reportId string) (bool, error) {
isLatest, err := g.isTheLatestReport(reportId)
if err != nil {
return false, err
}
if !isLatest {
return false, exceptions.NewImproperOperateError("不能删除非最新期数的报表。")
}
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.forceDeleteReport(tx, reportId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("end_user_detail")
cache.AbolishRelation(fmt.Sprintf("report_%s", reportId))
return result, nil
}
// 从此处开始为删除园区相关的内容部分
func (_GodModeService) deleteSpecificMaintenance(tx *xorm.Session, parkId, maintenanceId string) (bool, error) {
res, err := tx.Exec("delete from maintenance_fee where park_id=? and id=?", parkId, maintenanceId)
if err != nil {
tx.Rollback()
return false, nil
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
return rows >= 0, err
}
}
func (_GodModeService) deleteAllMaintenance(tx *xorm.Session, parkId string) (bool, error) {
res, err := tx.Exec("delete from maintenance_fee where park_id=?", parkId)
if err != nil {
tx.Rollback()
return false, nil
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
return rows >= 0, err
}
}
func (_GodModeService) deleteAllMeters(tx *xorm.Session, parkId string) (bool, error) {
res, err := tx.Exec("delete from meter_04kv where park_id=?", parkId)
if err != nil {
tx.Rollback()
return false, nil
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
return rows >= 0, err
}
}
func (_GodModeService) deletePark(tx *xorm.Session, parkId string) (bool, error) {
res, err := tx.Exec("delete from park where id=?", parkId)
if err != nil {
tx.Rollback()
return false, nil
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
return rows >= 0, err
}
}
func (g _GodModeService) RemoveSpecificMaintenance(parkId, maintenanceId string) (bool, error) {
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.deleteSpecificMaintenance(tx, parkId, maintenanceId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("maintenance_fee")
cache.AbolishRelation(fmt.Sprintf("maintenance_fee_%s", maintenanceId))
return result, nil
}
func (g _GodModeService) RemoveAllMaintenance(parkId string) (bool, error) {
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.deleteAllMaintenance(tx, parkId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("maintenance_fee")
return result, nil
}
func (g _GodModeService) RemoveAllMeters(parkId string) (bool, error) {
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.deleteAllMeters(tx, parkId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("meter_04kv")
return result, nil
}
func (g _GodModeService) erasePark(tx *xorm.Session, parkId string) (bool, error) {
var reportIds = make([]string, 0)
err := tx.
Table(new(model.Report)).
Where(builder.Eq{"park_id": parkId}).
NoAutoCondition().
Select("id").
Find(&reportIds)
if err != nil {
tx.Rollback()
return false, err
}
var result = true
for _, id := range reportIds {
r, err := g.forceDeleteReport(tx, id)
if err != nil {
return false, err
}
result = result && r
}
r, err := g.deleteAllMaintenance(tx, parkId)
if err != nil {
return false, err
}
result = result && r
r, err = g.deleteAllMeters(tx, parkId)
if err != nil {
return false, err
}
result = result && r
r, err = g.deletePark(tx, parkId)
if err != nil {
return false, err
}
result = result && r
return result, err
}
func (g _GodModeService) RemovePark(parkId string) (bool, error) {
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
result, err := g.erasePark(tx, parkId)
if err != nil {
return false, err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation("park")
cache.AbolishRelation(fmt.Sprintf("park_%s", parkId))
return result, nil
}
// 从此处开始为删除用户相关的部分
func (g _GodModeService) DeleteUser(userId string) (bool, error) {
tx := global.DBConn.NewSession()
if err := tx.Begin(); err != nil {
return false, err
}
defer tx.Close()
var parkIds = make([]string, 0)
err := tx.
Table(new(model.Park)).
Where(builder.Eq{"user_id": userId}).
NoAutoCondition().
Unscoped().
Select("id").
Find(&parkIds)
if err != nil {
tx.Rollback()
return false, err
}
var result = true
for _, p := range parkIds {
r, err := g.erasePark(tx, p)
if err != nil {
return false, err
}
result = result && r
}
// 删除用户服务计费数据。
res, err := tx.Exec("delete from user_charge where user_id=?", userId)
if err != nil {
tx.Rollback()
return false, err
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
result = result && (rows >= 0)
}
// 删除用户详细信息数据
res, err = tx.Exec("delete from user_detail where id=?", userId)
if err != nil {
tx.Rollback()
return false, err
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
result = result && (rows >= 0)
}
// 删除用户基本索引数据
res, err = tx.Exec("delete from `user` where id=?", userId)
if err != nil {
tx.Rollback()
return false, err
}
if rows, err := res.RowsAffected(); err != nil {
tx.Rollback()
return false, err
} else {
result = result && (rows >= 0)
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return false, err
}
cache.AbolishRelation(fmt.Sprintf("user_%s", userId))
cache.AbolishRelation("user")
cache.AbolishRelation("park")
cache.AbolishRelation("report")
cache.AbolishRelation("charge")
return result, nil
}