package controller import ( "electricity_bill_calc/logger" "electricity_bill_calc/repository" "electricity_bill_calc/response" "electricity_bill_calc/security" "electricity_bill_calc/service" "electricity_bill_calc/tools" "electricity_bill_calc/types" "electricity_bill_calc/vo" "fmt" "github.com/gofiber/fiber/v2" "github.com/jinzhu/copier" "github.com/samber/lo" "go.uber.org/zap" ) var tenementLog = logger.Named("Handler", "Tenement") func InitializeTenementHandler(router *fiber.App) { router.Get("/tenement/choice", security.EnterpriseAuthorize, listTenementForChoice) router.Get("/tenement/:pid", security.EnterpriseAuthorize, listTenement) router.Put("/tenement/:pid/:tid", security.EnterpriseAuthorize, updateTenement) router.Get("/tenement/:pid/:tid", security.EnterpriseAuthorize, getTenementDetail) router.Get("/tenement/:pid/:tid/meter", security.EnterpriseAuthorize, listMeters) router.Post("/tenement/:pid/:tid/move/out", security.EnterpriseAuthorize, moveOutTenement) router.Post("/tenement/:pid", security.EnterpriseAuthorize, addTenement) router.Post("/tenement/:pid/:tid/binding", security.EnterpriseAuthorize, bindMeterToTenement) //TODO: 2023-07-19再apiFox上该请求是个PUT请求,后端接收是个POST请求,不知道是否有误或是缺少对应请求(apiFox测试请求返回值为405) router.Post("/tenement/:pid/:tid/move/out", security.EnterpriseAuthorize, moveOutTenement) router.Post("/tenement/:pid", security.EnterpriseAuthorize, addTenement) router.Post("/tenement/:pid/:tid/binding", security.EnterpriseAuthorize, bindMeterToTenement) //TODO: 2023-07-19再apiFox上该请求是个PUT请求,后端接收是个POST请求,不知道是否有误或是缺少对应请求(apiFox测试请求返回值为405) router.Post("/tenement/:pid/:tid/binding/:code/unbind", security.EnterpriseAuthorize, unbindMeterFromTenement) } // 列出园区中的商户 func listTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") tenementLog.Info("列出园区中的商户", zap.String("Park", parkId)) if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } page := c.QueryInt("page", 1) keyword := tools.EmptyToNil(c.Query("keyword")) building := tools.EmptyToNil(c.Query("building")) startDate, err := types.ParseDatep(c.Query("startDate")) if err != nil { tenementLog.Error("列出园区中的商户失败,未能解析查询开始日期", zap.Error(err)) return result.BadRequest(err.Error()) } endDate, err := types.ParseDatep(c.Query("endDate")) if err != nil { tenementLog.Error("列出园区中的商户失败,未能解析查询结束日期", zap.Error(err)) return result.BadRequest(err.Error()) } state := c.QueryInt("state", 0) tenements, total, err := repository.TenementRepository.ListTenements(parkId, uint(page), keyword, building, startDate, endDate, state) if err != nil { tenementLog.Error("列出园区中的商户失败,未能获取商户列表", zap.Error(err)) return result.Error(fiber.StatusInternalServerError, err.Error()) } tenementsResponse := make([]*vo.TenementQueryResponse, 0) copier.Copy(&tenementsResponse, &tenements) return result.Success( "已经获取到要查询的商户。", response.NewPagedResponse(page, total).ToMap(), fiber.Map{ "tenements": tenementsResponse, }, ) } // 列出指定商户下所有的表计 func listMeters(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") tenementLog.Info("列出指定商户下所有的表计", zap.String("Park", parkId), zap.String("Tenement", tenementId)) meters, err := service.TenementService.ListMeter(parkId, tenementId) if err != nil { tenementLog.Error("列出指定商户下所有的表计失败,未能获取表计列表", zap.Error(err)) return result.Error(fiber.StatusInternalServerError, err.Error()) } return result.Success( "已经获取到要查询的表计。", fiber.Map{ "meters": meters, }, ) } // 增加一个新的商户 func addTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementLog.Info("增加一个新的商户", zap.String("Park", parkId)) var form vo.TenementCreationForm if err := c.BodyParser(&form); err != nil { tenementLog.Error("增加一个新的商户失败,未能解析要添加的商户信息", zap.Error(err)) return result.BadRequest(fmt.Sprintf("无法解析要添加的商户信息,%s", err.Error())) } err := service.TenementService.CreateTenementRecord(parkId, &form) if err != nil { tenementLog.Error("增加一个新的商户失败,未能添加商户记录", zap.Error(err)) return result.NotAccept(fmt.Sprintf("无法添加商户记录,%s", err.Error())) } return result.Success("已经成功添加商户。") } // 给指定商户绑定一个新的表计 func bindMeterToTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") if len(tenementId) == 0 { tenementLog.Error("给指定商户绑定一个新的表计失败,未指定商户。") return result.BadRequest("未指定商户。") } tenementLog.Info("向指定商户绑定一个表计。", zap.String("Park", parkId), zap.String("Tenement", tenementId)) var form vo.MeterReadingFormWithCode if err := c.BodyParser(&form); err != nil { tenementLog.Error("给指定商户绑定一个新的表计失败,未能解析要绑定的表计信息", zap.Error(err)) return result.BadRequest(fmt.Sprintf("无法解析要绑定的表计信息,%s", err.Error())) } if !form.MeterReadingForm.Validate() { tenementLog.Error("给指定商户绑定一个新的表计失败,表计读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。") return result.NotAccept("表计读数不能正确配平,尖锋电量、峰电量、谷电量之和超过总电量。") } err := service.TenementService.BindMeter(parkId, tenementId, form.Code, &form.MeterReadingForm) if err != nil { tenementLog.Error("给指定商户绑定一个新的表计失败,未能绑定表计", zap.Error(err)) return result.NotAccept(fmt.Sprintf("无法绑定表计,%s", err.Error())) } return result.Success("已经成功绑定表计。") } // 从指定商户下解除一个表计的绑定 func unbindMeterFromTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") if len(tenementId) == 0 { tenementLog.Error("从指定商户下解除一个表计的绑定失败,未指定商户。") return result.BadRequest("未指定商户。") } meterCode := c.Params("code") if len(meterCode) == 0 { tenementLog.Error("从指定商户下解除一个表计的绑定失败,未指定表计。") return result.BadRequest("未指定表计。") } tenementLog.Info("从指定商户处解绑一个表计。", zap.String("Park", parkId), zap.String("Tenement", tenementId), zap.String("Meter", meterCode)) var form vo.MeterReadingForm if err := c.BodyParser(&form); err != nil { tenementLog.Error("从指定商户下解除一个表计的绑定失败,未能解析要解除绑定的表计抄表数据。", zap.Error(err)) return result.BadRequest(fmt.Sprintf("无法解析要解除绑定的表计抄表数据,%s", err.Error())) } err := service.TenementService.UnbindMeter(parkId, tenementId, meterCode, &form) if err != nil { tenementLog.Error("从指定商户下解除一个表计的绑定失败,未能解除绑定表计。", zap.Error(err)) return result.NotAccept(fmt.Sprintf("无法解除绑定表计,%s", err.Error())) } return result.Success("已经成功解除表计绑定。") } // 修改指定商户的详细信息 func updateTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") if len(tenementId) == 0 { tenementLog.Error("修改指定商户的详细信息失败,未指定商户。") return result.BadRequest("未指定商户。") } tenementLog.Info("修改指定商户的详细信息。", zap.String("Park", parkId), zap.String("Tenement", tenementId)) var form vo.TenementCreationForm if err := c.BodyParser(&form); err != nil { tenementLog.Error("修改指定商户的详细信息失败,未能解析要修改的商户信息", zap.Error(err)) return result.BadRequest(fmt.Sprintf("无法解析要修改的商户信息,%s", err.Error())) } err := repository.TenementRepository.UpdateTenement(parkId, tenementId, &form) if err != nil { tenementLog.Error("修改指定商户的详细信息失败,未能修改商户信息", zap.Error(err)) return result.NotAccept(fmt.Sprintf("无法修改商户信息,%s", err.Error())) } return result.Success("商户信息修改成功。") } // 迁出指定园区中的商户 func moveOutTenement(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") if len(tenementId) == 0 { tenementLog.Error("迁出指定园区中的商户失败,未指定商户。") return result.BadRequest("未指定商户。") } tenementLog.Info("迁出指定园区中的商户。", zap.String("Park", parkId), zap.String("Tenement", tenementId)) var readings []*vo.MeterReadingFormWithCode if err := c.BodyParser(&readings); err != nil { tenementLog.Error("迁出指定园区中的商户失败,未能解析要迁出商户的抄表数据。", zap.Error(err)) return result.BadRequest(fmt.Sprintf("无法解析要迁出商户的抄表数据,%s", err.Error())) } err := service.TenementService.MoveOutTenement(parkId, tenementId, readings) if err != nil { tenementLog.Error("迁出指定园区中的商户失败,未能迁出商户。", zap.Error(err)) return result.NotAccept(fmt.Sprintf("无法迁出商户,%s", err.Error())) } return result.Success("商户迁出成功。") } // 列出园区中的商户列表,主要用于下拉列表 func listTenementForChoice(c *fiber.Ctx) error { result := response.NewResult(c) session, err := _retreiveSession(c) if err != nil { tenementLog.Error("列出园区中的商户列表失败,未能获取当前用户会话信息", zap.Error(err)) return result.Unauthorized("未能获取当前用户会话信息。") } parkId := tools.EmptyToNil(c.Params("pid")) if parkId != nil && len(*parkId) > 0 { if pass, err := checkParkBelongs(*parkId, tenementLog, c, &result); !pass { return err } } tenementLog.Info("列出园区中的商户列表,主要用于下拉列表。", zap.String("Ent", session.Uid), zap.Stringp("Park", parkId)) keyword := tools.EmptyToNil(c.Query("keyword")) limit := c.QueryInt("limit", 6) tenements, err := repository.TenementRepository.ListForSelect(session.Uid, parkId, keyword, lo.ToPtr(uint(limit))) if err != nil { tenementLog.Error("列出园区中的商户列表失败,未能获取商户列表", zap.Error(err)) return result.NotFound(fmt.Sprintf("未能获取商户列表,%s", err.Error())) } var tenementsResponse []*vo.SimplifiedTenementResponse copier.Copy(&tenementsResponse, &tenements) return result.Success( "已经获取到要查询的商户。", fiber.Map{ "tenements": tenementsResponse, }, ) } // 获取指定园区中指定商户的详细信息 func getTenementDetail(c *fiber.Ctx) error { result := response.NewResult(c) parkId := c.Params("pid") if pass, err := checkParkBelongs(parkId, tenementLog, c, &result); !pass { return err } tenementId := c.Params("tid") if len(tenementId) == 0 { tenementLog.Error("获取指定园区中指定商户的详细信息失败,未指定商户。") return result.BadRequest("未指定商户。") } tenementLog.Info("获取指定园区中指定商户的详细信息。", zap.String("Park", parkId), zap.String("Tenement", tenementId)) tenement, err := repository.TenementRepository.RetrieveTenementDetail(parkId, tenementId) if err != nil { tenementLog.Error("获取指定园区中指定商户的详细信息失败,未能获取商户信息", zap.Error(err)) return result.NotFound(fmt.Sprintf("未能获取商户信息,%s", err.Error())) } var detail vo.TenementDetailResponse copier.Copy(&detail, &tenement) return result.Success( "已经获取到要查询的商户。", fiber.Map{ "tenement": detail, }, ) }