Browse Source

system: depth update user

Yi 1 week ago
parent
commit
24dcbd808a

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250526084133-ef8acddd1868
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250526094651-0cef600addd0
 	gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3

+ 6 - 0
go.sum

@@ -121,6 +121,12 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250526081009-3766cd67d900 h1:+QN7wEwm
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250526081009-3766cd67d900/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250526084133-ef8acddd1868 h1:JTXSBH8VO9uUweNyEy5o/OngSJ4xx2WmYVBn+/1vp1w=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250526084133-ef8acddd1868/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526090502-532d86d767de h1:+jPEpEljv/JyEPKFuNCeDbqbnyjCoGB14fucLMX+nv0=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526090502-532d86d767de/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526091836-9e663a273679 h1:Ulh1ArxGRApui9E5UVNbCa3Cv3NnZIs3vbIpNy/3lA0=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526091836-9e663a273679/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526094651-0cef600addd0 h1:nGmhS9BKCMgCz9zEVmygDIPNrolI9lb9uLV6NfoTxWE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250526094651-0cef600addd0/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b h1:w05MxH7yqveRlaRbxHhbif5YjPrJFodRPfOjYhXn7Zk=
 gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b/go.mod h1:8tF25X6pE9WkFCczlNAC0K2mrjwKvhhp02I7o0HtDxY=
 gitee.com/xuyiping_admin/pkg v0.0.0-20250514071642-f92d2ac9a85d h1:vBXmMRggF7mZVPGRDgavZ87igJgkezwX0a3v1/XtIMQ=

+ 6 - 1
http/handler/system/dept.go

@@ -74,7 +74,12 @@ func DepCreateOrUpdate(c *gin.Context) {
 }
 
 func DeptTree(c *gin.Context) {
-	res, err := middleware.Dependency(c).StoreEventHub.OpsService.SystemDeptTree(c)
+	var req pasturePb.SearchDeptRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	res, err := middleware.Dependency(c).StoreEventHub.OpsService.SystemDeptTree(c, &req)
 	if err != nil {
 		apierr.ClassifiedAbort(c, err)
 		return

+ 1 - 1
http/route/system_api.go

@@ -49,7 +49,7 @@ func SystemAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		systemRoute.POST("/dept/list", system.DeptList)
 		systemRoute.DELETE("/dept/:id", system.DepIsShow)
 		systemRoute.POST("/dept/createOrUpdate", system.DepCreateOrUpdate)
-		systemRoute.GET("/dept/tree", system.DeptTree)
+		systemRoute.POST("/dept/tree", system.DeptTree)
 
 		// 登录用户的相关接口
 		systemRoute.GET("/user/menu", system.GetUserMenu)

+ 2 - 0
model/indicators_data.go

@@ -57,6 +57,8 @@ const (
 	FemaleCalfRate                   = "female_calf_rate"                      // 母犊率
 	WeaningDailyWeight               = "weaning_daily_weight"                  // 断奶日增重
 	Day60DieRate                     = "day60_die_rate"                        // 60日龄死亡率
+	AdultPrematureBirthRate          = "adult_premature_birth_rate"            // 成母牛早产率
+	YouthPrematureBirthRate          = "youth_premature_birth_rate"            // 青年牛早产率
 )
 
 type IndicatorsData struct {

+ 22 - 6
model/system_dept.go

@@ -25,6 +25,20 @@ func (s *SystemDept) TableName() string {
 	return "system_dept"
 }
 
+func NewSystemDept(req *pasturePb.SearchDeptRequest) *SystemDept {
+	return &SystemDept{
+		PastureId: int64(req.PastureId),
+		Name:      req.Name,
+		Remarks:   req.Remarks,
+		DeptType:  pasturePb.Depth_Company,
+		LeaderId:  int64(req.LeaderId),
+		ParentId:  int64(req.ParentId),
+
+		IsShow:   pasturePb.IsShow_Ok,
+		IsDelete: pasturePb.IsShow_Ok,
+	}
+}
+
 func NewSystemDeptInit(pasture *AppPastureList) *SystemDept {
 	return &SystemDept{
 		PastureId: pasture.Id,
@@ -35,7 +49,7 @@ func NewSystemDeptInit(pasture *AppPastureList) *SystemDept {
 		ParentId:  0,
 		Sort:      0,
 		IsShow:    pasturePb.IsShow_Ok,
-		IsDelete:  pasturePb.IsShow_No,
+		IsDelete:  pasturePb.IsShow_Ok,
 	}
 }
 
@@ -63,6 +77,7 @@ func (s SystemDeptSlice) ToPB(systemUserList []*SystemUser) []*pasturePb.SearchD
 			Sort:       d.Sort,
 			IsShow:     d.IsShow,
 			IsDelete:   d.IsDelete,
+			PastureId:  int32(d.PastureId),
 			CreatedAt:  int32(d.CreatedAt),
 			UpdatedAt:  int32(d.UpdatedAt),
 		}
@@ -82,11 +97,12 @@ func (s SystemDeptSlice) ToTree() []*pasturePb.DeptTreeData {
 
 	for i, v := range s {
 		res[i] = &pasturePb.DeptTreeData{
-			Id:       int32(v.Id),
-			ParentId: int32(v.ParentId),
-			Name:     v.Name,
-
-			Children: make([]*pasturePb.DeptTreeData, 0),
+			Id:        int32(v.Id),
+			ParentId:  int32(v.ParentId),
+			Name:      v.Name,
+			IsShow:    v.IsShow,
+			PastureId: int32(v.PastureId),
+			Children:  make([]*pasturePb.DeptTreeData, 0),
 		}
 	}
 	// 构建树

+ 13 - 0
model/system_user.go

@@ -3,6 +3,7 @@ package model
 import (
 	"fmt"
 	"net/http"
+	"strconv"
 	"strings"
 	"time"
 
@@ -53,6 +54,18 @@ func (s *SystemUser) SystemUserFormat(userRoles []*SystemRole, pastures []*opera
 	}
 }
 
+func (s *SystemUser) GetPastureIds() []int64 {
+	res := make([]int64, 0)
+	if s.PastureIds != "" {
+		pastureIds := strings.Split(s.PastureIds, ",")
+		for _, idStr := range pastureIds {
+			id, _ := strconv.Atoi(idStr)
+			res = append(res, int64(id))
+		}
+	}
+	return res
+}
+
 type UserModel struct {
 	SystemUser *SystemUser
 	AppPasture *AppPastureList

+ 1 - 1
module/backend/interface.go

@@ -93,7 +93,7 @@ type SystemService interface {
 	SearchSystemDeptList(ctx context.Context, req *pasturePb.SearchDeptRequest, pagination *pasturePb.PaginationModel) (*pasturePb.SearchDeptResponse, error)
 	SystemDepDelete(ctx context.Context, id int64) error
 	SystemDeptCreateOrUpdate(ctx context.Context, req *pasturePb.SearchDeptRequest) error
-	SystemDeptTree(ctx context.Context) (*pasturePb.DeptTreeResponse, error)
+	SystemDeptTree(ctx context.Context, req *pasturePb.SearchDeptRequest) (*pasturePb.DeptTreeResponse, error)
 
 	// SearchUserPastureList 用户相关牧场列表
 	SearchUserPastureList(ctx context.Context) (*pasturePb.SystemUserPastureListResponse, error)

+ 122 - 27
module/backend/system_service_more.go

@@ -6,7 +6,10 @@ import (
 	"fmt"
 	"kpt-pasture/model"
 	"net/http"
-	"strings"
+
+	"go.uber.org/zap"
+
+	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
 
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 	operationPb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/operation"
@@ -161,27 +164,33 @@ func (s *StoreEntry) SystemDepDelete(ctx context.Context, id int64) error {
 
 func (s *StoreEntry) SystemDeptCreateOrUpdate(ctx context.Context, req *pasturePb.SearchDeptRequest) error {
 	if req.Id > 0 {
-		barn := &model.SystemDept{Id: int64(req.Id)}
-		if err := s.DB.Model(&model.SystemDept{}).First(barn).Error; err != nil {
-			if !errors.Is(err, gorm.ErrRecordNotFound) {
-				return xerr.WithStack(err)
-			}
+		systemDept := &model.SystemDept{}
+		if err := s.DB.Model(new(model.SystemDept)).
+			Where("id = ?", req.Id).
+			Where("pasture_id = ?", req.PastureId).
+			First(systemDept).Error; err != nil {
+			zaplog.Error("部门信息错误", zap.Any("req", req))
+		}
+		if err := s.DB.Model(systemDept).
+			Where("id = ?", req.Id).
+			Where("pasture_id = ?", req.PastureId).
+			Updates(map[string]interface{}{
+				"name":      req.Name,
+				"parent_id": req.ParentId,
+				"sort":      req.Sort,
+				"remarks":   req.Remarks,
+				"is_show":   req.IsShow,
+				"is_delete": req.IsDelete,
+			}).Error; err != nil {
+			return xerr.WithStack(err)
+		}
+	} else {
+		newSystemDepth := model.NewSystemDept(req)
+		if err := s.DB.Model(&model.SystemDept{}).Create(newSystemDepth).Error; err != nil {
+			return xerr.WithStack(err)
 		}
 	}
-	if err := s.DB.Model(&model.SystemDept{}).Where(map[string]interface{}{
-		"id": req.Id,
-	}).Assign(map[string]interface{}{
-		"name":      req.Name,
-		"sort":      req.Sort,
-		"parent_id": req.ParentId,
-		"remarks":   req.Remarks,
-		"is_delete": operationPb.IsShow_OK,
-		"is_show":   req.IsShow,
-		"dept_type": pasturePb.Depth_Department,
-		"leader_id": req.LeaderId,
-	}).FirstOrCreate(&model.SystemDept{}).Error; err != nil {
-		return xerr.WithStack(err)
-	}
+
 	return nil
 }
 
@@ -203,7 +212,7 @@ func (s *StoreEntry) SearchUserPastureList(ctx context.Context) (*pasturePb.Syst
 	}, err
 }
 
-func (s *StoreEntry) SystemDeptTree(ctx context.Context) (*pasturePb.DeptTreeResponse, error) {
+func (s *StoreEntry) SystemDeptTree(ctx context.Context, req *pasturePb.SearchDeptRequest) (*pasturePb.DeptTreeResponse, error) {
 	currentUser, err := s.GetCurrentSystemUser(ctx)
 	if err != nil {
 		return nil, xerr.WithStack(err)
@@ -214,18 +223,104 @@ func (s *StoreEntry) SystemDeptTree(ctx context.Context) (*pasturePb.DeptTreeRes
 		return nil, xerr.Customf("请先将该用户绑定牧场!谢谢!")
 	}
 
-	pastureIds := strings.Split(pastureIdsStr, ",")
+	pastureIds := currentUser.GetPastureIds()
 	systemDeptList := make([]*model.SystemDept, 0)
-	if err = s.DB.Model(new(model.SystemDept)).
-		Where("is_delete = ?", pasturePb.IsShow_Ok).
-		Where("is_show = ?", pasturePb.IsShow_Ok).
-		Where("pasture_id IN ?", pastureIds).
-		Find(&systemDeptList).Error; err != nil {
+
+	pref := s.DB.Model(new(model.SystemDept)).
+		Where("is_delete = ?", pasturePb.IsShow_Ok)
+
+	if req.PastureId > 0 {
+		pref.Where("pasture_id = ?", req.PastureId)
+	} else {
+		pref.Where("pasture_id IN ?", pastureIds)
+	}
+
+	if req.Name != "" {
+		pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%"))
+	}
+
+	if req.IsShow > 0 {
+		pref.Where("is_show = ?", req.IsShow)
+	}
+
+	if err = pref.Find(&systemDeptList).Error; err != nil {
 		return nil, xerr.WithStack(err)
 	}
+
+	if req.Name != "" {
+		parentDepths, err := s.findAllParentDepths(ctx, systemDeptList, pastureIds)
+		if err != nil {
+			return nil, xerr.WithStack(err)
+		}
+		systemDeptList = append(systemDeptList, parentDepths...)
+	}
+
+	// 没有搜到部门数据,默认返回所有牧场一级数据
+	if len(systemDeptList) == 0 {
+		systemDeptList = s.SearchDepthPastureList(ctx)
+	}
+
 	return &pasturePb.DeptTreeResponse{
 		Code: http.StatusOK,
 		Msg:  "ok",
 		Data: model.SystemDeptSlice(systemDeptList).ToTree(),
 	}, nil
 }
+
+func (s *StoreEntry) SearchDepthPastureList(ctx context.Context) []*model.SystemDept {
+	systemDeptList := make([]*model.SystemDept, 0)
+	currentUser, err := s.GetCurrentSystemUser(ctx)
+	if err != nil {
+		return systemDeptList
+	}
+
+	pastureIds := currentUser.GetPastureIds()
+	if err = s.DB.Model(new(model.SystemDept)).
+		Where("is_delete = ?", pasturePb.IsShow_Ok).
+		Where("pasture_id IN ?", pastureIds).
+		Where("parent_id = ?", 0).
+		Find(&systemDeptList).Error; err != nil {
+		return systemDeptList
+	}
+	return systemDeptList
+}
+
+// findAllParentDepths 递归查找所有上级部门
+func (s *StoreEntry) findAllParentDepths(ctx context.Context, depths []*model.SystemDept, pastureIds []int64) ([]*model.SystemDept, error) {
+	var allDepths []*model.SystemDept
+	var parentIDs []int64
+	foundDepths := make(map[int64]bool)
+
+	// 收集所有需要查找的父部门ID
+	for _, dept := range depths {
+		if dept.ParentId > 0 && !foundDepths[dept.ParentId] {
+			parentIDs = append(parentIDs, dept.ParentId)
+			foundDepths[dept.ParentId] = true
+		}
+	}
+
+	if len(parentIDs) == 0 {
+		return allDepths, nil
+	}
+
+	// 查询这些父部门
+	var parentDepths []*model.SystemDept
+	if err := s.DB.Model(new(model.SystemDept)).
+		Where("id IN ?", parentIDs).
+		Where("pasture_id IN ?", pastureIds).
+		Where("is_delete = ?", pasturePb.IsShow_Ok).
+		Find(&parentDepths).Error; err != nil {
+		return nil, err
+	}
+
+	// 递归查找更上级的部门
+	higherParents, err := s.findAllParentDepths(ctx, parentDepths, pastureIds)
+	if err != nil {
+		return nil, err
+	}
+
+	allDepths = append(allDepths, parentDepths...)
+	allDepths = append(allDepths, higherParents...)
+
+	return allDepths, nil
+}

+ 4 - 1
module/crontab/cow_cron.go

@@ -167,7 +167,10 @@ func (e *Entry) Indicators() error {
 			pastureIndicatorList = e.WeaningDailyWeight(pastureList, startTime, endTime)
 		case model.Day60DieRate:
 			pastureIndicatorList = e.DayDieRate(pastureList, startTime, endTime, 60)
-
+		case model.AdultPrematureBirthRate:
+			pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, true)
+		case model.YouthPrematureBirthRate:
+			pastureIndicatorList = e.PrematureBirthRate(pastureList, startTime, endTime, 60, false)
 		}
 
 		for pastureId, value := range pastureIndicatorList {

+ 35 - 0
module/crontab/cow_indicators_calf.go

@@ -172,3 +172,38 @@ func (e *Entry) DayDieRate(pastureList []*model.AppPastureList, startAt, endAt i
 	}
 	return res
 }
+
+// PrematureBirthRate 牛只早产率
+func (e *Entry) PrematureBirthRate(pastureList []*model.AppPastureList, startAt, endAt int64, pregnancyAge int32, isAdult bool) map[int64]string {
+	res := make(map[int64]string)
+	for _, pasture := range pastureList {
+		eventCalvingList := make([]*model.EventCalving, 0)
+		pref := e.DB.Model(new(model.EventCalving)).
+			Where("pasture_id = ?", pasture.Id).
+			Where("status = ?", pasturePb.IsShow_Ok).
+			Where("reality_day BETWEEN ? AND ?", startAt, endAt)
+		if isAdult {
+			pref = pref.Where("lact > ?", 1)
+		} else {
+			pref = pref.Where("lact = ?", 0)
+		}
+
+		if err := pref.Find(&eventCalvingList).Error; err != nil {
+			zaplog.Error("PrematureBirthRate", zap.Any("pasture_id", pasture.Id), zap.Any("err", err))
+		}
+
+		count := float64(0)
+		for _, v := range eventCalvingList {
+			if v.DayAge <= pregnancyAge {
+				count++
+			}
+		}
+
+		if count > 0 {
+			res[pasture.Id] = fmt.Sprintf("%.2f", count/float64(len(eventCalvingList)))
+		} else {
+			res[pasture.Id] = "0"
+		}
+	}
+	return res
+}