package controller 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" "fmt" "net/http" "strconv" "github.com/gofiber/fiber/v2" "github.com/samber/lo" "github.com/shopspring/decimal" ) func InitializeEndUserController(router *fiber.App) { router.Get("/report/:rid/submeter", security.EnterpriseAuthorize, fetchEndUserInReport) 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 *fiber.Ctx) error { result := response.NewResult(c) requestReportId := c.Params("rid") if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure { return err } keyword := c.Query("keyword") requestPage, err := strconv.Atoi(c.Query("page", "1")) if err != nil { return result.NotAccept("查询参数[page]格式不正确。") } endUsers, totalItem, err := service.EndUserService.SearchEndUserRecord(requestReportId, keyword, requestPage) if err != nil { return result.NotFound(err.Error()) } return result.Json( http.StatusOK, "已获取到符合条件的终端用户集合", response.NewPagedResponse(requestPage, totalItem).ToMap(), fiber.Map{"meters": endUsers}, ) } func downloadEndUserRegisterTemplate(c *fiber.Ctx) error { result := response.NewResult(c) requestReportId := c.Params("rid") users, err := service.EndUserService.AllEndUserRecord(requestReportId) if err != nil { return result.NotFound(err.Error()) } reportIndex, err := service.ReportService.RetreiveReportIndex(requestReportId) if err != nil { return result.NotFound(err.Error()) } park, err := service.ParkService.FetchParkDetail(reportIndex.ParkId) if err != nil { return result.NotFound(err.Error()) } meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId) if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } if meterType == -1 { return result.NotFound("未能确定用户表计类型。") } c.Status(http.StatusOK) c.Set("Content-Type", "application/octet-stream") c.Set("Content-Transfer-Encoding", "binary") c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=抄表记录-%s-%s.xlsx", park.Name, reportIndex.Period.Format("2006-01"))) gen := lo.Ternary[excel.ExcelTemplateGenerator]( meterType == 0, excel.NewMeterNonPVExcelTemplateGenerator(), excel.NewMeterPVExcelTemplateGenerator(), ) defer gen.Close() gen.WriteMeterData(users) gen.WriteTo(c.Response().BodyWriter()) return nil } func uploadEndUserRegisterTemplate(c *fiber.Ctx) error { result := response.NewResult(c) requestReportId := c.Params("rid") if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure { return err } meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId) if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } if meterType == -1 { return result.NotFound("未能确定用户表计类型。") } uploadedFile, err := c.FormFile("data") if err != nil { return result.NotAccept("没有接收到上传的档案文件。") } archiveFile, err := uploadedFile.Open() if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } if meterType == 0 { errs := service.EndUserService.BatchImportNonPVRegister(requestReportId, archiveFile) if errs.Len() > 0 { return result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", fiber.Map{"errors": errs.Errs}) } } else { errs := service.EndUserService.BatchImportPVRegister(requestReportId, archiveFile) if errs.Len() > 0 { return result.Json(http.StatusInternalServerError, "上传抄表文件存在解析错误", fiber.Map{"errors": errs.Errs}) } } return result.Json(http.StatusOK, "已经成功完成抄表记录的导入。", fiber.Map{"errors": make([]error, 0)}) } type ModifyEndUserRegisterFormData struct { CurrentPeriodOverall decimal.NullDecimal `json:"currentPeriodOverall" form:"currentPeriodOverall"` CurrentPeriodCritical decimal.NullDecimal `json:"currentPeriodCritical" form:"currentPeriodCritical"` CurrentPeriodPeak decimal.NullDecimal `json:"currentPeriodPeak" form:"currentPeriodPeak"` CurrentPeriodValley decimal.NullDecimal `json:"currentPeriodValley" form:"currentPeriodValley"` AdjustOverall decimal.NullDecimal `json:"adjustOverall" form:"adjustOverall"` AdjustCritical decimal.NullDecimal `json:"adjustCritical" form:"adjustCritical"` AdjustPeak decimal.NullDecimal `json:"adjustPeak" form:"adjustPeak"` AdjustValley decimal.NullDecimal `json:"adjustValley" form:"adjustValley"` } func modifyEndUserRegisterRecord(c *fiber.Ctx) error { result := response.NewResult(c) requestReportId := c.Params("rid") if ensure, err := ensureReportBelongs(c, &result, requestReportId); !ensure { return err } meterType, err := service.ReportService.RetreiveParkEndUserMeterType(requestReportId) if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } if meterType == -1 { return result.NotFound("未能确定用户表计类型。") } requestParkId := c.Params("pid") requestMeterId := c.Params("mid") formData := new(ModifyEndUserRegisterFormData) if err := c.BodyParser(formData); err != nil { return result.UnableToParse("无法解析提交的数据。") } meter, err := service.EndUserService.FetchSpecificEndUserRecord(requestReportId, requestParkId, requestMeterId) if err != nil { return result.NotFound(err.Error()) } if formData.CurrentPeriodOverall.Valid { meter.CurrentPeriodOverall = formData.CurrentPeriodOverall.Decimal } if formData.CurrentPeriodCritical.Valid { meter.CurrentPeriodCritical = formData.CurrentPeriodCritical.Decimal } if formData.CurrentPeriodPeak.Valid { meter.CurrentPeriodPeak = formData.CurrentPeriodPeak.Decimal } if formData.CurrentPeriodValley.Valid { meter.CurrentPeriodValley = formData.CurrentPeriodValley.Decimal } if formData.AdjustOverall.Valid { meter.AdjustOverall = formData.AdjustOverall.Decimal } if formData.AdjustCritical.Valid { meter.AdjustCritical = formData.AdjustCritical.Decimal } if formData.AdjustPeak.Valid { meter.AdjustPeak = formData.AdjustPeak.Decimal } if formData.AdjustValley.Valid { meter.AdjustValley = formData.AdjustValley.Decimal } valid, err := meter.Validate() if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } if !valid { return result.NotAccept("抄表数据合法性验证失败。") } ctx, cancel := global.TimeoutContext() defer cancel() tx, err := global.DB.BeginTx(ctx, &sql.TxOptions{}) if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } err = service.EndUserService.UpdateEndUserRegisterRecord(&tx, &ctx, *meter) if err != nil { tx.Rollback() return result.Error(http.StatusInternalServerError, err.Error()) } err = tx.Commit() if err != nil { tx.Rollback() return result.Error(http.StatusInternalServerError, err.Error()) } return result.Success("指定终端用户抄表记录已经更新。") } func statEndUserInPeriod(c *fiber.Ctx) error { result := response.NewResult(c) session, err := _retreiveSession(c) if err != nil { return result.Unauthorized(err.Error()) } requestUser := lo. If(session.Type == model.USER_TYPE_ENT, session.Uid). Else(c.Query("user")) requestPark := c.Query("park") if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT { if ensure, err := ensureParkBelongs(c, &result, requestPark); !ensure { return err } } startDate := c.Query("start") endDate := c.Query("end") stat, err := service.EndUserService.StatEndUserRecordInPeriod(requestUser, requestPark, startDate, endDate) if err != nil { return result.Error(http.StatusInternalServerError, err.Error()) } return result.Success( "已经完成终端用户的费用统计", fiber.Map{"details": stat}, ) }