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(¤tRecords) 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 }