forked from free-lancers/electricity_bill_calc_service
		
	enhance(fee):基本完成物业附加费部分的运算。
This commit is contained in:
		| @@ -6,9 +6,11 @@ import ( | ||||
| 	"electricity_bill_calc/security" | ||||
| 	"electricity_bill_calc/service" | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/jinzhu/copier" | ||||
| 	"github.com/samber/lo" | ||||
| 	"github.com/shopspring/decimal" | ||||
| ) | ||||
|  | ||||
| @@ -18,6 +20,7 @@ func InitializeMaintenanceFeeController(router *gin.Engine) { | ||||
| 	router.PUT("/maintenance/fee/:mid", security.EnterpriseAuthorize, modifyMaintenanceFeeRecord) | ||||
| 	router.PUT("/maintenance/fee/:mid/enabled", security.EnterpriseAuthorize, changeMaintenanceFeeState) | ||||
| 	router.DELETE("/maintenance/fee/:mid", security.EnterpriseAuthorize, deleteMaintenanceFee) | ||||
| 	router.GET("/additional/charges", security.MustAuthenticated, statAdditionalCharges) | ||||
| } | ||||
|  | ||||
| func ensureMaintenanceFeeBelongs(c *gin.Context, result *response.Result, requestMaintenanceFeeId string) bool { | ||||
| @@ -46,34 +49,51 @@ func listMaintenanceFees(c *gin.Context) { | ||||
| 		return | ||||
| 	} | ||||
| 	requestPark := c.DefaultQuery("park", "") | ||||
| 	requestPeriod := c.DefaultQuery("period", "") | ||||
| 	requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1")) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, "不能解析给定的参数[page]。") | ||||
| 		return | ||||
| 	} | ||||
| 	if len(requestPark) > 0 { | ||||
| 		if !ensureParkBelongs(c, result, requestPark) { | ||||
| 			return | ||||
| 		} | ||||
| 		fees, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{requestPark}) | ||||
| 		fees, total, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{requestPark}, requestPeriod, requestPage) | ||||
| 		if err != nil { | ||||
| 			result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 			return | ||||
| 		} | ||||
| 		result.Json(http.StatusOK, "已获取指定园区下的维护费记录", gin.H{"fees": fees}) | ||||
| 		result.Json( | ||||
| 			http.StatusOK, | ||||
| 			"已获取指定园区下的维护费记录", | ||||
| 			response.NewPagedResponse(requestPage, total).ToMap(), | ||||
| 			gin.H{"fees": fees}, | ||||
| 		) | ||||
| 	} else { | ||||
| 		parkIds, err := service.ParkService.AllParkIds(userSession.Uid) | ||||
| 		if err != nil { | ||||
| 			result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 			return | ||||
| 		} | ||||
| 		fees, err := service.MaintenanceFeeService.ListMaintenanceFees(parkIds) | ||||
| 		fees, total, err := service.MaintenanceFeeService.ListMaintenanceFees(parkIds, requestPeriod, requestPage) | ||||
| 		if err != nil { | ||||
| 			result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 			return | ||||
| 		} | ||||
| 		result.Json(http.StatusOK, "已获取指定用户下的所有维护费记录。", gin.H{"fees": fees}) | ||||
| 		result.Json( | ||||
| 			http.StatusOK, | ||||
| 			"已获取指定用户下的所有维护费记录。", | ||||
| 			response.NewPagedResponse(requestPage, total).ToMap(), | ||||
| 			gin.H{"fees": fees}, | ||||
| 		) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type _FeeCreationFormData struct { | ||||
| 	ParkId string          `json:"parkId" form:"parkId"` | ||||
| 	Name   string          `json:"name" form:"name"` | ||||
| 	Period string          `json:"period" form:"period"` | ||||
| 	Fee    decimal.Decimal `json:"fee" form:"fee"` | ||||
| 	Memo   *string         `json:"memo" form:"memo"` | ||||
| } | ||||
| @@ -152,3 +172,38 @@ func deleteMaintenanceFee(c *gin.Context) { | ||||
| 	} | ||||
| 	result.Deleted("指定维护费条目已删除。") | ||||
| } | ||||
|  | ||||
| func statAdditionalCharges(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	session, err := _retreiveSession(c) | ||||
| 	if err != nil { | ||||
| 		result.Unauthorized(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	requestUser := lo. | ||||
| 		If(session.Type == model.USER_TYPE_ENT, session.Uid). | ||||
| 		Else(c.DefaultQuery("user", "")) | ||||
| 	requestPark := c.DefaultQuery("park", "") | ||||
| 	if len(requestPark) > 0 && session.Type == model.USER_TYPE_ENT { | ||||
| 		if !ensureParkBelongs(c, result, requestPark) { | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 	period := c.DefaultQuery("period", "") | ||||
| 	keyword := c.DefaultQuery("keyword", "") | ||||
| 	requestPage, err := strconv.Atoi(c.DefaultQuery("page", "1")) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, "不能解析给定的参数[page]。") | ||||
| 		return | ||||
| 	} | ||||
| 	fees, total, err := service.MaintenanceFeeService.QueryAdditiionalCharges(requestUser, requestPark, period, keyword, requestPage) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Success( | ||||
| 		"已经成功获取到物业附加费的统计记录。", | ||||
| 		response.NewPagedResponse(requestPage, total).ToMap(), | ||||
| 		gin.H{"charges": fees}, | ||||
| 	) | ||||
| } | ||||
|   | ||||
| @@ -11,7 +11,6 @@ import ( | ||||
| 	"strconv" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/fufuok/utils" | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/jinzhu/copier" | ||||
| 	"github.com/samber/lo" | ||||
| @@ -26,12 +25,6 @@ func InitializeReportController(router *gin.Engine) { | ||||
| 	router.PUT("/report/:rid/summary", security.EnterpriseAuthorize, fillReportSummary) | ||||
| 	router.GET("/report/:rid/summary/calculate", security.EnterpriseAuthorize, testCalculateReportSummary) | ||||
| 	router.POST("/report/:rid/summary/calculate", security.EnterpriseAuthorize, progressReportSummary) | ||||
| 	router.GET("/report/:rid/maintenance", security.EnterpriseAuthorize, fetchWillDilutedFees) | ||||
| 	router.POST("/report/:rid/maintenance", security.EnterpriseAuthorize, createTemporaryWillDilutedFee) | ||||
| 	router.POST("/report/:rid/maintenance/import", security.EnterpriseAuthorize, importPredefinedMaintenanceFees) | ||||
| 	router.PUT("/report/:rid/maintenance/:mid", security.EnterpriseAuthorize, modifyWillDilutedFee) | ||||
| 	router.DELETE("/report/:rid/maintenance/:mid", security.EnterpriseAuthorize, deleteTemporaryWillDilutedFee) | ||||
| 	router.PUT("/report/:rid/step/diluted/fees", security.EnterpriseAuthorize, progressReportWillDilutedFee) | ||||
| 	router.PUT("/report/:rid/step/meter/register", security.EnterpriseAuthorize, progressEndUserRegister) | ||||
| 	router.POST("/report/:rid/publish", security.EnterpriseAuthorize, publishReport) | ||||
| 	router.GET("/reports", security.MustAuthenticated, searchReports) | ||||
| @@ -208,161 +201,6 @@ func progressReportSummary(c *gin.Context) { | ||||
| 	result.Success("已经完成园区概况的计算,并可以进行到下一步骤。") | ||||
| } | ||||
|  | ||||
| func fetchWillDilutedFees(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	fees, err := service.ReportService.FetchWillDulutedMaintenanceFees(requestReportId) | ||||
| 	if err != nil { | ||||
| 		result.NotFound(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Json(http.StatusOK, "待摊薄费用已经获取到。", gin.H{"fees": fees}) | ||||
| } | ||||
|  | ||||
| type DilutedFeeCreationFormData struct { | ||||
| 	ParkId string          `json:"parkId" form:"parkId"` | ||||
| 	Name   string          `json:"name" form:"name"` | ||||
| 	Fee    decimal.Decimal `json:"fee" form:"fee"` | ||||
| 	Memo   *string         `json:"memo" form:"memo"` | ||||
| } | ||||
|  | ||||
| func createTemporaryWillDilutedFee(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	formData := new(DilutedFeeCreationFormData) | ||||
| 	c.BindJSON(formData) | ||||
| 	report, err := service.ReportService.RetreiveReportIndex(requestReportId) | ||||
| 	if err != nil { | ||||
| 		result.NotFound(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	if formData.ParkId != report.ParkId { | ||||
| 		result.NotAccept("选择的园区与公示报表所属的园区不一致。") | ||||
| 		return | ||||
| 	} | ||||
| 	newWillDilutedFee := new(model.WillDilutedFee) | ||||
| 	copier.Copy(newWillDilutedFee, formData) | ||||
| 	newWillDilutedFee.ReportId = report.Id | ||||
| 	err = service.ReportService.CreateTemporaryWillDilutedMaintenanceFee(*newWillDilutedFee) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Created("公示报表中所要使用的临时待摊薄费用已添加。") | ||||
| } | ||||
|  | ||||
| func importPredefinedMaintenanceFees(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	report, err := service.ReportService.RetreiveReportIndex(requestReportId) | ||||
| 	if err != nil { | ||||
| 		result.NotFound(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	maintenanceFees, err := service.MaintenanceFeeService.ListMaintenanceFees([]string{report.ParkId}) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	enabledMaintenanceFees := lo.Filter( | ||||
| 		maintenanceFees, | ||||
| 		func(elem model.MaintenanceFee, index int) bool { | ||||
| 			return elem.Enabled | ||||
| 		}, | ||||
| 	) | ||||
| 	if len(enabledMaintenanceFees) == 0 { | ||||
| 		result.NotFound("没有找到可供导入的配电维护费记录。") | ||||
| 		return | ||||
| 	} | ||||
| 	dilutedFees := lo.Map( | ||||
| 		enabledMaintenanceFees, | ||||
| 		func(elem model.MaintenanceFee, index int) model.WillDilutedFee { | ||||
| 			fee := &model.WillDilutedFee{ | ||||
| 				Id:       utils.UUIDString(), | ||||
| 				ReportId: report.Id, | ||||
| 				SourceId: lo.ToPtr(elem.Id), | ||||
| 				Name:     elem.Name, | ||||
| 				Fee:      elem.Fee, | ||||
| 				Memo:     elem.Memo, | ||||
| 			} | ||||
| 			return *fee | ||||
| 		}, | ||||
| 	) | ||||
| 	err = service.ReportService.BatchSaveMaintenanceFee(report.Id, dilutedFees) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Created("预定义的配电维护费已经导入。") | ||||
| } | ||||
|  | ||||
| type DilutedFeeModificationFormData struct { | ||||
| 	Name *string         `json:"name,omitempty" form:"name"` | ||||
| 	Fee  decimal.Decimal `json:"fee" form:"fee"` | ||||
| 	Memo *string         `json:"memo,omitempty" form:"memo"` | ||||
| } | ||||
|  | ||||
| func modifyWillDilutedFee(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	requestFeeId := c.Param("mid") | ||||
| 	formData := new(DilutedFeeModificationFormData) | ||||
| 	c.BindJSON(formData) | ||||
| 	updateValues := tools.ConvertStructToMap(formData) | ||||
| 	err := service.ReportService.UpdateMaintenanceFee(requestFeeId, updateValues) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Updated("指定待摊薄费用信息已经更新。") | ||||
| } | ||||
|  | ||||
| func deleteTemporaryWillDilutedFee(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	requestFeeId := c.Param("mid") | ||||
| 	err := service.ReportService.DeleteWillDilutedFee(requestFeeId) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Deleted("指定待摊薄费用信息已经删除。") | ||||
| } | ||||
|  | ||||
| func progressReportWillDilutedFee(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
| 	if !ensureReportBelongs(c, result, requestReportId) { | ||||
| 		return | ||||
| 	} | ||||
| 	report, err := service.ReportService.RetreiveReportIndex(requestReportId) | ||||
| 	if err != nil { | ||||
| 		result.NotFound(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	err = service.ReportService.ProgressReportWillDilutedFee(*report) | ||||
| 	if err != nil { | ||||
| 		result.Error(http.StatusInternalServerError, err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	result.Success("待摊薄费用编辑步骤已经完成。") | ||||
| } | ||||
|  | ||||
| func progressEndUserRegister(c *gin.Context) { | ||||
| 	result := response.NewResult(c) | ||||
| 	requestReportId := c.Param("rid") | ||||
|   | ||||
| @@ -19,6 +19,7 @@ type MaintenanceFee struct { | ||||
| 	Fee                decimal.Decimal `bun:"type:numeric,notnull" json:"fee"` | ||||
| 	Memo               *string         `bun:"type:text" json:"memo"` | ||||
| 	Enabled            bool            `bun:",notnull" json:"enabled"` | ||||
| 	Park               Park            `bun:"rel:belongs-to,join:park_id=id"` | ||||
| } | ||||
|  | ||||
| var _ bun.BeforeAppendModelHook = (*MaintenanceFee)(nil) | ||||
| @@ -34,3 +35,14 @@ func (f *MaintenanceFee) BeforeAppendModel(ctx context.Context, query bun.Query) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type AdditionalCharge struct { | ||||
| 	ParkId          string               `json:"parkId"` | ||||
| 	Period          string               `json:"period"` | ||||
| 	Fee             decimal.Decimal      `json:"fee"` | ||||
| 	Price           decimal.Decimal      `json:"price"` | ||||
| 	QuarterPrice    decimal.Decimal      `json:"quarterPrice"` | ||||
| 	SemiAnnualPrice decimal.Decimal      `json:"semiAnnualPrice"` | ||||
| 	Enterprise      UserDetailSimplified `json:"user"` | ||||
| 	Park            Park                 `json:"park"` | ||||
| } | ||||
|   | ||||
| @@ -2,14 +2,17 @@ package service | ||||
|  | ||||
| import ( | ||||
| 	"electricity_bill_calc/cache" | ||||
| 	"electricity_bill_calc/config" | ||||
| 	"electricity_bill_calc/exceptions" | ||||
| 	"electricity_bill_calc/global" | ||||
| 	"electricity_bill_calc/logger" | ||||
| 	"electricity_bill_calc/model" | ||||
| 	"fmt" | ||||
|  | ||||
| 	mapset "github.com/deckarep/golang-set/v2" | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/samber/lo" | ||||
| 	"github.com/shopspring/decimal" | ||||
| 	"github.com/uptrace/bun" | ||||
| 	"go.uber.org/zap" | ||||
| ) | ||||
| @@ -22,9 +25,14 @@ var MaintenanceFeeService = _MaintenanceFeeService{ | ||||
| 	l: logger.Named("Service", "maintenance"), | ||||
| } | ||||
|  | ||||
| func (_MaintenanceFeeService) ListMaintenanceFees(pid []string) ([]model.MaintenanceFee, error) { | ||||
| 	if fees, _ := cache.RetreiveSearch[[]model.MaintenanceFee]("maintenance_fee", pid...); fees != nil { | ||||
| 		return *fees, nil | ||||
| func (_MaintenanceFeeService) ListMaintenanceFees(pid []string, period string, requestPage int) ([]model.MaintenanceFee, int64, error) { | ||||
| 	conditions := []string{fmt.Sprintf("%d", requestPage)} | ||||
| 	conditions = append(conditions, pid...) | ||||
| 	conditions = append(conditions, period) | ||||
| 	if cachedTotal, err := cache.RetreiveCount("maintenance_fee", conditions...); cachedTotal != -1 && err == nil { | ||||
| 		if fees, _ := cache.RetreiveSearch[[]model.MaintenanceFee]("maintenance_fee", conditions...); fees != nil { | ||||
| 			return *fees, cachedTotal, nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var ( | ||||
| @@ -34,23 +42,30 @@ func (_MaintenanceFeeService) ListMaintenanceFees(pid []string) ([]model.Mainten | ||||
| 	if len(pid) > 0 { | ||||
| 		cond = cond.Where("park_id in (?)", bun.In(pid)) | ||||
| 	} else { | ||||
| 		return make([]model.MaintenanceFee, 0), exceptions.NewIllegalArgumentsError("必须给定所要请求的至少一个园区", "park_id") | ||||
| 		return make([]model.MaintenanceFee, 0), 0, exceptions.NewIllegalArgumentsError("必须给定所要请求的至少一个园区", "park_id") | ||||
| 	} | ||||
| 	if len(period) > 0 { | ||||
| 		cond = cond.Where("period = ?", period) | ||||
| 	} | ||||
|  | ||||
| 	ctx, cancel := global.TimeoutContext() | ||||
| 	defer cancel() | ||||
|  | ||||
| 	err := cond.Order("created_at desc").Scan(ctx) | ||||
| 	startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize | ||||
| 	total, err := cond.Order("period desc", "created_at desc"). | ||||
| 		Limit(config.ServiceSettings.ItemsPageSize). | ||||
| 		Offset(startItem). | ||||
| 		ScanAndCount(ctx) | ||||
| 	if err != nil { | ||||
| 		return make([]model.MaintenanceFee, 0), err | ||||
| 		return make([]model.MaintenanceFee, 0), 0, fmt.Errorf("附加费查询出现错误,%w", err) | ||||
| 	} | ||||
| 	relations := lo.Map(fees, func(f model.MaintenanceFee, _ int) string { | ||||
| 		return fmt.Sprintf("maintenance_fee:%s", f.Id) | ||||
| 	}) | ||||
| 	relations = append(relations, "maintenance_fee", "park") | ||||
|  | ||||
| 	cache.CacheSearch(fees, relations, "maintenance_fee", pid...) | ||||
| 	return fees, nil | ||||
| 	cache.CacheCount(relations, "maintenance_fee", int64(total), conditions...) | ||||
| 	cache.CacheSearch(fees, relations, "maintenance_fee", conditions...) | ||||
| 	return fees, int64(total), nil | ||||
| } | ||||
|  | ||||
| func (_MaintenanceFeeService) CreateMaintenanceFeeRecord(fee model.MaintenanceFee) error { | ||||
| @@ -77,7 +92,7 @@ func (_MaintenanceFeeService) ModifyMaintenanceFee(fee model.MaintenanceFee) err | ||||
| 		Exec(ctx) | ||||
| 	if err != nil { | ||||
| 		if rows, _ := res.RowsAffected(); rows == 0 { | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的维护费记录。") | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的附加费记录。") | ||||
| 		} else { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -96,7 +111,7 @@ func (_MaintenanceFeeService) ChangeMaintenanceFeeState(fid string, state bool) | ||||
| 		Exec(ctx) | ||||
| 	if err != nil { | ||||
| 		if rows, err := res.RowsAffected(); rows == 0 { | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的维护费记录。") | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的附加费记录。") | ||||
| 		} else { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -114,7 +129,7 @@ func (_MaintenanceFeeService) DeleteMaintenanceFee(fid string) error { | ||||
| 		Exec(ctx) | ||||
| 	if err != nil { | ||||
| 		if rows, err := res.RowsAffected(); rows == 0 { | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的维护费记录。") | ||||
| 			return exceptions.NewNotFoundError("未能找到匹配的附加费记录。") | ||||
| 		} else { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -148,8 +163,130 @@ func (_MaintenanceFeeService) EnsureFeeBelongs(uid, mid string) (bool, error) { | ||||
| 		return acc || false | ||||
| 	}, false) | ||||
| 	if !exists { | ||||
| 		return false, exceptions.NewNotFoundError("指定维护费所属园区未找到。") | ||||
| 		return false, exceptions.NewNotFoundError("指定附加费所属园区未找到。") | ||||
| 	} | ||||
| 	cache.CacheExists([]string{fmt.Sprintf("maintenance_fee:%s", mid), "maintenance_fee", "park"}, "maintenance_fee", mid, uid) | ||||
| 	return exists, nil | ||||
| } | ||||
|  | ||||
| type _FeeStat struct { | ||||
| 	ParkId string | ||||
| 	Period string | ||||
| 	Total  decimal.Decimal | ||||
| } | ||||
|  | ||||
| func (f _MaintenanceFeeService) QueryAdditiionalCharges(uid, pid, period, keyword string, requestPage int) ([]model.AdditionalCharge, int64, error) { | ||||
| 	var ( | ||||
| 		conditions = []string{fmt.Sprintf("%d", requestPage)} | ||||
| 		statFees   = make([]_FeeStat, 0) | ||||
| 		cond       = global.DB.NewSelect(). | ||||
| 				Model((*model.MaintenanceFee)(nil)). | ||||
| 				Relation("Park", func(q *bun.SelectQuery) *bun.SelectQuery { | ||||
| 				return q.ExcludeColumn("*") | ||||
| 			}). | ||||
| 			Relation("Park.Enterprise", func(q *bun.SelectQuery) *bun.SelectQuery { | ||||
| 				return q.ExcludeColumn("*") | ||||
| 			}). | ||||
| 			Where("m.enabled = ?", true) | ||||
| 	) | ||||
| 	if len(uid) > 0 { | ||||
| 		cond = cond.Where("park__enterprise.id = ?", uid) | ||||
| 		conditions = append(conditions, uid) | ||||
| 	} else { | ||||
| 		conditions = append(conditions, "_") | ||||
| 	} | ||||
| 	if len(pid) > 0 { | ||||
| 		cond = cond.Where("park.id = ?", pid) | ||||
| 		conditions = append(conditions, pid) | ||||
| 	} else { | ||||
| 		conditions = append(conditions, "_") | ||||
| 	} | ||||
| 	if len(period) > 0 { | ||||
| 		cond = cond.Where("m.period = ?", period) | ||||
| 		conditions = append(conditions, period) | ||||
| 	} else { | ||||
| 		conditions = append(conditions, "_") | ||||
| 	} | ||||
| 	if len(keyword) > 0 { | ||||
| 		keywordCond := "%" + keyword + "%" | ||||
| 		cond = cond.WhereGroup(" and ", func(q *bun.SelectQuery) *bun.SelectQuery { | ||||
| 			return q.Where("park__enterprise.name like ?", keywordCond). | ||||
| 				WhereOr("park__enterprise.abbr like ?", keywordCond). | ||||
| 				WhereOr("park.name like ?", keywordCond). | ||||
| 				WhereOr("park.abbr like ?", keywordCond). | ||||
| 				WhereOr("park.address like ?", keywordCond) | ||||
| 		}) | ||||
| 		conditions = append(conditions, keyword) | ||||
| 	} else { | ||||
| 		conditions = append(conditions, "_") | ||||
| 	} | ||||
|  | ||||
| 	if cachedTotal, err := cache.RetreiveCount("additional_charge", conditions...); cachedTotal != -1 && err == nil { | ||||
| 		if cachedData, _ := cache.RetreiveSearch[[]model.AdditionalCharge]("additional_charge", conditions...); cachedData != nil { | ||||
| 			return *cachedData, cachedTotal, nil | ||||
| 		} | ||||
| 	} | ||||
| 	ctx, cancel := global.TimeoutContext(24) | ||||
| 	defer cancel() | ||||
|  | ||||
| 	startItem := (requestPage - 1) * config.ServiceSettings.ItemsPageSize | ||||
|  | ||||
| 	total, err := cond.ColumnExpr("sum(?) as total", bun.Ident("fee")). | ||||
| 		Column("park_id", "period"). | ||||
| 		Group("park_id", "period"). | ||||
| 		Order("period desc"). | ||||
| 		Limit(config.ServiceSettings.ItemsPageSize). | ||||
| 		Offset(startItem). | ||||
| 		ScanAndCount(ctx, &statFees) | ||||
| 	if err != nil { | ||||
| 		return make([]model.AdditionalCharge, 0), 0, fmt.Errorf("获取附加费统计信息出现错误,%w", err) | ||||
| 	} | ||||
| 	parkIds := lo.Reduce( | ||||
| 		statFees, | ||||
| 		func(acc mapset.Set[string], elem _FeeStat, _ int) mapset.Set[string] { | ||||
| 			acc.Add(elem.ParkId) | ||||
| 			return acc | ||||
| 		}, | ||||
| 		mapset.NewSet[string](), | ||||
| 	) | ||||
| 	parks := make([]model.Park, 0) | ||||
| 	err = global.DB.NewSelect().Model(&parks).Relation("Enterprise"). | ||||
| 		Where("p.id in (?)", bun.In(parkIds.ToSlice())). | ||||
| 		Scan(ctx) | ||||
| 	if err != nil { | ||||
| 		return make([]model.AdditionalCharge, 0), 0, fmt.Errorf("获取园区信息出现错误,%w", err) | ||||
| 	} | ||||
| 	f.l.Debug("Park ids", zap.Any("ids", parkIds)) | ||||
| 	f.l.Debug("Check fees", zap.Any("fees", statFees)) | ||||
| 	assembledStat := lo.Reduce( | ||||
| 		statFees, | ||||
| 		func(acc []model.AdditionalCharge, elem _FeeStat, _ int) []model.AdditionalCharge { | ||||
| 			park, has := lo.Find(parks, func(p model.Park) bool { | ||||
| 				return p.Id == elem.ParkId | ||||
| 			}) | ||||
| 			f.l.Debug("Park detection.", zap.Bool("has", has), zap.Any("park", park)) | ||||
| 			if has { | ||||
| 				if !park.Area.Valid || park.Area.Decimal.Equal(decimal.Zero) { | ||||
| 					return acc | ||||
| 				} | ||||
| 				price := elem.Total.Div(park.Area.Decimal).RoundBank(8) | ||||
| 				return append(acc, model.AdditionalCharge{ | ||||
| 					ParkId:          elem.ParkId, | ||||
| 					Period:          elem.Period, | ||||
| 					Fee:             elem.Total, | ||||
| 					Price:           price, | ||||
| 					QuarterPrice:    price.Div(decimal.NewFromInt(4)), | ||||
| 					SemiAnnualPrice: price.Div(decimal.NewFromInt(2)), | ||||
| 					Enterprise:      model.FromUserDetail(*park.Enterprise), | ||||
| 					Park:            park, | ||||
| 				}) | ||||
| 			} else { | ||||
| 				return acc | ||||
| 			} | ||||
| 		}, | ||||
| 		make([]model.AdditionalCharge, 0), | ||||
| 	) | ||||
| 	cache.CacheCount([]string{"maintenance_fee"}, "additional_charge", int64(total), conditions...) | ||||
| 	cache.CacheSearch(assembledStat, []string{"maintenance_fee"}, "additional_charge", conditions...) | ||||
| 	return assembledStat, int64(total), nil | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user