Browse Source

event: sale

Yi 1 month ago
parent
commit
71d01b0c61

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module kpt-pasture
 go 1.17
 
 require (
-	gitee.com/xuyiping_admin/go_proto v0.0.0-20250224070445-464185db4857
+	gitee.com/xuyiping_admin/go_proto v0.0.0-20250224085851-f9b6573afee1
 	gitee.com/xuyiping_admin/pkg v0.0.0-20241108060137-caea58c59f5b
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/eclipse/paho.mqtt.golang v1.4.3

+ 6 - 0
go.sum

@@ -232,6 +232,12 @@ gitee.com/xuyiping_admin/go_proto v0.0.0-20250224061833-6c7b2a3558b8 h1:PYUFDZcD
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250224061833-6c7b2a3558b8/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250224070445-464185db4857 h1:fYMnYdzFo/crU6pXCiCpvFtLBsztN8/gyrXJaYrgj64=
 gitee.com/xuyiping_admin/go_proto v0.0.0-20250224070445-464185db4857/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224081427-8e93b44844e3 h1:nu6bj5oaJafnP4IcboUz+27RiKVUU5FC7nLAFZUvnPM=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224081427-8e93b44844e3/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224084846-f92b34bad24c h1:SfrHXto4YBe3cUAJ91ANdaNYBhc90Vys4o6dCsYLO6M=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224084846-f92b34bad24c/go.mod h1:BKrFW6YLDectlQcQk3FYKBeXvjEiodAKJ5rq7O/QiPE=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224085851-f9b6573afee1 h1:sG6KjT6KTR7l8MzkCGzq5WhR8ggaR5G98yRhYLSdIcI=
+gitee.com/xuyiping_admin/go_proto v0.0.0-20250224085851-f9b6573afee1/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=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

+ 21 - 0
http/handler/event/event_base.go

@@ -334,3 +334,24 @@ func CowSale(c *gin.Context) {
 		Data: &operationPb.Success{Success: true},
 	})
 }
+
+func CowSaleList(c *gin.Context) {
+	var req pasturePb.EventCowSaleRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	pagination := &pasturePb.PaginationModel{
+		Page:       int32(c.GetInt(middleware.Page)),
+		PageSize:   int32(c.GetInt(middleware.PageSize)),
+		PageOffset: int32(c.GetInt(middleware.PageOffset)),
+	}
+
+	res, err := middleware.Dependency(c).StoreEventHub.OpsService.CowSaleList(c, &req, pagination)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}

+ 43 - 0
http/handler/pasture/seme_time.go

@@ -137,3 +137,46 @@ func SystemBasicEdit(c *gin.Context) {
 		Data: &operationPb.Success{Success: true},
 	})
 }
+
+func SaleDealerCreateOrUpdate(c *gin.Context) {
+	var req pasturePb.DealerItem
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	if err := valid.ValidateStruct(&req,
+		valid.Field(&req.Name, valid.Required),
+		valid.Field(&req.Phone, valid.Required),
+		valid.Field(&req.Contacts, valid.Required),
+	); err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+
+	if err := middleware.BackendOperation(c).OpsService.CreateOrUpdateDealer(c, &req); err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+
+	ginutil.JSONResp(c, &operationPb.CommonOK{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &operationPb.Success{Success: true},
+	})
+}
+
+func SaleDealerList(c *gin.Context) {
+	var req pasturePb.SearchNameRequest
+	if err := ginutil.BindProto(c, &req); err != nil {
+		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
+		return
+	}
+
+	res, err := middleware.BackendOperation(c).OpsService.SearchDealerList(c, &req)
+	if err != nil {
+		apierr.ClassifiedAbort(c, err)
+		return
+	}
+	ginutil.JSONResp(c, res)
+}

+ 1 - 1
http/route/event_api.go

@@ -66,6 +66,6 @@ func EventAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		eventRoute.PUT("/cow/ear/number", event.CowEarNumber)
 		// 牛只销售
 		eventRoute.POST("/sale/create", event.CowSale)
-		eventRoute.POST("/sale/list", event.CowSale)
+		eventRoute.POST("/sale/list", event.CowSaleList)
 	}
 }

+ 4 - 0
http/route/pasture_api.go

@@ -51,6 +51,10 @@ func PastureManageAPI(opts ...func(engine *gin.Engine)) func(s *gin.Engine) {
 		pastureRoute.POST("/same/time/list", pasture.SameTimeList)
 		pastureRoute.PUT("/same/time/is_show/:id", pasture.SameTimeIsShow)
 
+		// 经销商相关
+		pastureRoute.POST("/dealer/createOrUpdate", pasture.SaleDealerCreateOrUpdate)
+		pastureRoute.POST("/dealer/list", pasture.SaleDealerList)
+
 		// 基础参数
 		pastureRoute.POST("/system/basic/list", pasture.SystemBasicList)
 		pastureRoute.POST("/system/basic/edit", pasture.SystemBasicEdit)

+ 56 - 1
model/event_sale.go

@@ -1,6 +1,7 @@
 package model
 
 import (
+	"strconv"
 	"strings"
 
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
@@ -33,7 +34,6 @@ func (e *EventSale) TableName() string {
 }
 
 func NewEventSale(pastureId int64, dealerInfo *SaleDealer, cowIds string, req *pasturePb.EventCowSale, operationUser, currUser *SystemUser) *EventSale {
-
 	return &EventSale{
 		PastureId:        pastureId,
 		DealerId:         dealerInfo.Id,
@@ -53,3 +53,58 @@ func NewEventSale(pastureId int64, dealerInfo *SaleDealer, cowIds string, req *p
 		MessageName:      currUser.Name,
 	}
 }
+
+type EventSaleSlice []*EventSale
+
+func (e EventSaleSlice) ToPB(eventSaleCarMap map[int64][]*EventSaleCar) []*pasturePb.EventCowSale {
+	res := make([]*pasturePb.EventCowSale, len(e))
+	for i, v := range e {
+		cowIds := make([]int32, 0)
+		if len(v.CowIds) > 0 {
+			for _, cowIdStr := range strings.Split(v.CowIds, ",") {
+				cowId, _ := strconv.Atoi(cowIdStr)
+				cowIds = append(cowIds, int32(cowId))
+			}
+		}
+
+		saleVehicleItems := make([]*pasturePb.SaleVehicleItem, 0)
+		eventSaleCarItems, ok := eventSaleCarMap[v.Id]
+		if ok {
+
+			for _, item := range eventSaleCarItems {
+				carCowIds := make([]int32, 0)
+				if len(item.CowIds) > 0 {
+					for _, cowIdStr := range strings.Split(item.CowIds, ",") {
+						carCowId, _ := strconv.Atoi(cowIdStr)
+						carCowIds = append(carCowIds, int32(carCowId))
+					}
+				}
+				saleVehicleItems = append(saleVehicleItems, &pasturePb.SaleVehicleItem{
+					CarNumber:         item.CarNumber,
+					CowCount:          item.CowCount,
+					CowWeight:         float32(item.CowWeight) / 1000,
+					OutboundTicket:    item.OutboundTicket,
+					WeighbridgePhotos: strings.Split(item.WeighbridgePhotos, ","),
+					VehiclePhotos:     strings.Split(item.CarPhotos, ","),
+					CowIds:            carCowIds,
+				})
+			}
+		}
+		res[i] = &pasturePb.EventCowSale{
+			DealerId:         v.DealerId,
+			DealerName:       v.DealerName,
+			SaleAt:           int32(v.SaleAt),
+			CowIds:           cowIds,
+			SaleAllWeight:    float32(v.SaleAllWeight) / 1000,
+			SaleAllPrice:     float32(v.SaleAllAmount),
+			SalePrice:        float32(v.SalePrice),
+			OperationId:      int32(v.OperationId),
+			OperationName:    v.OperationName,
+			Remarks:          v.Remarks,
+			SaleTicket:       strings.Split(v.SaleTicker, ","),
+			QuarantineReport: strings.Split(v.QuarantineReport, ","),
+			SaleVehicleItems: nil,
+		}
+	}
+	return res
+}

+ 7 - 3
model/event_sale_car.go

@@ -8,10 +8,12 @@ import (
 
 type EventSaleCar struct {
 	Id                int64  `json:"id"`
+	PastureId         int64  `json:"pastureId"`
 	SaleId            int64  `json:"saleId"`
 	SaleAt            int64  `json:"saleAt"`
 	CarNumber         string `json:"carNumber"`
 	CowCount          int32  `json:"cowCount"`
+	CowWeight         int64  `json:"cowWeight"`
 	CowIds            string `json:"cowIds"`
 	OutboundTicket    string `json:"outbound_ticket"`
 	WeighbridgePhotos string `json:"weighbridgePhotos"`
@@ -24,8 +26,9 @@ func (e *EventSaleCar) TableName() string {
 	return "event_sale_car"
 }
 
-func NewEventSaleCar(saleId, saleAt int64, saleVehicleItem *pasturePb.SaleVehicleItem) *EventSaleCar {
+func NewEventSaleCar(pastureId, saleId, saleAt int64, saleVehicleItem *pasturePb.SaleVehicleItem) *EventSaleCar {
 	return &EventSaleCar{
+		PastureId:         pastureId,
 		SaleId:            saleId,
 		SaleAt:            saleAt,
 		CarNumber:         saleVehicleItem.CarNumber,
@@ -34,13 +37,14 @@ func NewEventSaleCar(saleId, saleAt int64, saleVehicleItem *pasturePb.SaleVehicl
 		OutboundTicket:    saleVehicleItem.OutboundTicket,
 		WeighbridgePhotos: strings.Join(saleVehicleItem.WeighbridgePhotos, ","),
 		CarPhotos:         strings.Join(saleVehicleItem.VehiclePhotos, ","),
+		CowWeight:         int64(saleVehicleItem.CowWeight * 1000),
 	}
 }
 
-func NewEventSaleCarList(saleId, saleAt int64, req []*pasturePb.SaleVehicleItem) []*EventSaleCar {
+func NewEventSaleCarList(pastureId, saleId, saleAt int64, req []*pasturePb.SaleVehicleItem) []*EventSaleCar {
 	res := make([]*EventSaleCar, 0)
 	for _, saleVehicleItem := range req {
-		res = append(res, NewEventSaleCar(saleId, saleAt, saleVehicleItem))
+		res = append(res, NewEventSaleCar(pastureId, saleId, saleAt, saleVehicleItem))
 	}
 	return res
 }

+ 42 - 6
model/sale_dealer.go

@@ -1,14 +1,50 @@
 package model
 
+import pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
+
 type SaleDealer struct {
-	Id        int32  `json:"id"`
-	Name      string `json:"name"`
-	Phone     string `json:"phone"`
-	Address   string `json:"address"`
-	CreatedAt int64  `json:"createdAt"`
-	UpdatedAt int64  `json:"updatedAt"`
+	Id        int32                 `json:"id"`
+	PastureId int64                 `json:"pastureId"`
+	Name      string                `json:"name"`
+	Contacts  string                `json:"contacts"`
+	Phone     string                `json:"phone"`
+	Address   string                `json:"address"`
+	Remarks   string                `json:"remarks"`
+	IsShow    pasturePb.IsShow_Kind `json:"isShow"`
+	CreatedAt int64                 `json:"createdAt"`
+	UpdatedAt int64                 `json:"updatedAt"`
 }
 
 func (s *SaleDealer) TableName() string {
 	return "sale_dealer"
 }
+
+func NewSaleDealer(pastureId int64, name, phone string) *SaleDealer {
+	return &SaleDealer{
+		PastureId: pastureId,
+		Name:      name,
+		Contacts:  "",
+		Phone:     phone,
+		Address:   "",
+		Remarks:   "",
+		IsShow:    pasturePb.IsShow_Ok,
+	}
+}
+
+type SaleDealerSlice []*SaleDealer
+
+func (s SaleDealerSlice) ToPB() []*pasturePb.DealerItem {
+	res := make([]*pasturePb.DealerItem, len(s))
+	for i, v := range s {
+		res[i] = &pasturePb.DealerItem{
+			Id:       v.Id,
+			Name:     v.Name,
+			Contacts: v.Contacts,
+			Address:  v.Address,
+			Phone:    v.Phone,
+			IsShow:   v.IsShow,
+			Remarks:  v.Remarks,
+		}
+	}
+	return res
+}

+ 58 - 1
module/backend/event_base_more.go

@@ -4,6 +4,7 @@ import (
 	"context"
 	"kpt-pasture/model"
 	"kpt-pasture/util"
+	"net/http"
 
 	pasturePb "gitee.com/xuyiping_admin/go_proto/proto/go/backend/cow"
 	"gitee.com/xuyiping_admin/pkg/logger/zaplog"
@@ -165,7 +166,7 @@ func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowS
 			return xerr.WithStack(err)
 		}
 
-		newEventSaleCarList := model.NewEventSaleCarList(newEventSale.Id, newEventSale.SaleAt, req.SaleVehicleItems)
+		newEventSaleCarList := model.NewEventSaleCarList(userModel.AppPasture.Id, newEventSale.Id, newEventSale.SaleAt, req.SaleVehicleItems)
 		if err = tx.Model(new(model.EventSaleCar)).Create(&newEventSaleCarList).Error; err != nil {
 			return xerr.WithStack(err)
 		}
@@ -188,3 +189,59 @@ func (s *StoreEntry) CowSaleCreate(ctx context.Context, req *pasturePb.EventCowS
 	}
 	return nil
 }
+
+func (s *StoreEntry) CowSaleList(ctx context.Context, req *pasturePb.EventCowSaleRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowSaleResponse, error) {
+	userModel, err := s.GetUserModel(ctx)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	eventSale := make([]*model.EventSale, 0)
+	var count int64
+	pref := s.DB.Model(new(model.EventSale)).Where("pasture_id = ?", userModel.AppPasture.Id)
+	if req.StartDayAt > 0 && req.EndDayAt > 0 && req.EndDayAt >= req.StartDayAt {
+		pref.Where("sale_at BETWEEN ? AND ?", req.StartDayAt, req.EndDayAt)
+	}
+	if req.DealerId > 0 {
+		pref.Where("dealer_id = ?", req.DealerId)
+	}
+
+	if err = pref.Order("a.id desc").
+		Count(&count).Limit(int(pagination.PageSize)).
+		Offset(int(pagination.PageOffset)).
+		Find(&eventSale).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	saleIds := make([]int64, 0)
+	for _, v := range eventSale {
+		saleIds = append(saleIds, v.Id)
+	}
+
+	eventSaleCarList := make([]*model.EventSaleCar, 0)
+	if err = s.DB.Model(new(model.EventSaleCar)).
+		Where("pasture_id = ?", userModel.AppPasture.Id).
+		Where("sale_id IN (?)", saleIds).
+		Find(&eventSaleCarList).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	eventSaleCarMap := make(map[int64][]*model.EventSaleCar)
+	for _, car := range eventSaleCarList {
+		if eventSaleCarMap[car.SaleId] == nil {
+			eventSaleCarMap[car.SaleId] = make([]*model.EventSaleCar, 0)
+		}
+		eventSaleCarMap[car.SaleId] = append(eventSaleCarMap[car.SaleId], car)
+	}
+
+	return &pasturePb.EventCowSaleResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &pasturePb.EventCowSaleData{
+			List:     model.EventSaleSlice(eventSale).ToPB(eventSaleCarMap),
+			Total:    int32(count),
+			PageSize: pagination.PageSize,
+			Page:     pagination.Page,
+		},
+	}, err
+}

+ 4 - 1
module/backend/interface.go

@@ -131,6 +131,9 @@ type PastureManageService interface {
 	CreatedOrUpdateImmunization(ctx context.Context, req *pasturePb.ImmunizationRequest) error
 	ImmunizationIsShow(ctx context.Context, id int64) error
 
+	CreateOrUpdateDealer(crx context.Context, req *pasturePb.DealerItem) error
+	SearchDealerList(crx context.Context, req *pasturePb.SearchNameRequest) (*pasturePb.SearchDealerResponse, error)
+
 	SystemBasicEdit(ctx context.Context, req *pasturePb.BaseDataConfigBatch) error
 	SystemBasicList(ctx context.Context) (*pasturePb.SearchBaseDataConfigResponse, error)
 }
@@ -209,7 +212,7 @@ type EventService interface {
 	SubmitEventLog(ctx context.Context, pastureId int64, cow *model.Cow, eventType pasturePb.EventType_Kind, exposeEstrusType pasturePb.ExposeEstrusType_Kind, req interface{}) *model.EventCowLog
 
 	CowSaleCreate(ctx context.Context, req *pasturePb.EventCowSale) error
-	//CowSaleList(ctx context.Context, req *pasturePb.EventCowSale) error
+	CowSaleList(ctx context.Context, req *pasturePb.EventCowSaleRequest, pagination *pasturePb.PaginationModel) (*pasturePb.EventCowSaleResponse, error)
 }
 
 //go:generate mockgen -destination mock/CowService.go -package kptservicemock kpt-pasture/module/backend CowService

+ 59 - 0
module/backend/pasture.go

@@ -411,3 +411,62 @@ func (s *StoreEntry) CreateOrUpdateCowSource(ctx context.Context, req *pasturePb
 	}
 	return nil
 }
+
+func (s *StoreEntry) CreateOrUpdateDealer(crx context.Context, req *pasturePb.DealerItem) error {
+	userModel, err := s.GetUserModel(crx)
+	if err != nil {
+		return xerr.WithStack(err)
+	}
+
+	if req.Id > 0 {
+		saleDealer := &model.SaleDealer{Id: req.Id}
+		if err = s.DB.Model(new(model.SaleDealer)).First(saleDealer).Error; err != nil {
+			if !errors.Is(err, gorm.ErrRecordNotFound) {
+				return xerr.WithStack(err)
+			}
+		}
+	}
+
+	if err = s.DB.Model(new(model.SaleDealer)).
+		Where(map[string]interface{}{
+			"id":         req.Id,
+			"pasture_id": userModel.AppPasture.Id,
+		}).Assign(map[string]interface{}{
+		"contacts": req.Contacts,
+		"phone":    req.Phone,
+		"name":     req.Name,
+		"remarks":  req.Remarks,
+		"is_show":  pasturePb.IsShow_Ok,
+	}).FirstOrCreate(new(model.SaleDealer)).Error; err != nil {
+		return xerr.WithStack(err)
+	}
+	return nil
+}
+
+func (s *StoreEntry) SearchDealerList(crx context.Context, req *pasturePb.SearchNameRequest) (*pasturePb.SearchDealerResponse, error) {
+	userModel, err := s.GetUserModel(crx)
+	if err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	saleDealerList := make([]*model.SaleDealer, 0)
+	pref := s.DB.Model(new(model.SaleDealer)).
+		Where("pasture_id = ?", userModel.AppPasture.Id)
+
+	if req.Name != "" {
+		pref.Where("name like ?", fmt.Sprintf("%s%s%s", "%", req.Name, "%"))
+	}
+
+	if err = pref.Where("is_show = ?", pasturePb.IsShow_Ok).Find(&saleDealerList).Error; err != nil {
+		return nil, xerr.WithStack(err)
+	}
+
+	return &pasturePb.SearchDealerResponse{
+		Code: http.StatusOK,
+		Msg:  "ok",
+		Data: &pasturePb.SearchDealerData{
+			List: model.SaleDealerSlice(saleDealerList).ToPB(),
+		},
+	}, nil
+
+}