Browse Source

拆分plan update 接口到stages.go

sun-pc 2 months ago
parent
commit
a6a99717cc
7 changed files with 163 additions and 47 deletions
  1. 2 1
      boxcost/api/bill-produce.go
  2. 2 1
      boxcost/api/bill-product.go
  3. 2 1
      boxcost/api/bill.go
  4. 36 11
      boxcost/api/plan.go
  5. 2 2
      boxcost/api/router.go
  6. 118 30
      boxcost/api/stages.go
  7. 1 1
      comm

+ 2 - 1
boxcost/api/bill-produce.go

@@ -288,7 +288,8 @@ func UpdateProduceBill(c *gin.Context, apictx *ApiSession) (interface{}, error)
 				DeliveryTime:   produce.DeliveryTime,
 			}
 		}
-		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx)
+		db := apictx.Svc.Mongo.GetCollection(repo.CollectionBillProduce)
+		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx, db)
 		if err != nil {
 			return nil, errors.New("该单据改动同步到产品失败")
 		}

+ 2 - 1
boxcost/api/bill-product.go

@@ -278,7 +278,8 @@ func UpdateProductBill(c *gin.Context, apictx *ApiSession) (interface{}, error)
 				DeliveryTime: product.DeliveryTime,
 			}
 		}
-		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx)
+		db := apictx.Svc.Mongo.GetCollection(repo.CollectionBillProduct)
+		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx, db)
 		if err != nil {
 			return nil, errors.New("该单据改动同步到产品失败")
 		}

+ 2 - 1
boxcost/api/bill.go

@@ -419,7 +419,8 @@ func UpdateBill(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 				IsChangePrice2: isInclude(paper.Price2Unit, units),
 			}
 		}
-		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx)
+		db := apictx.Svc.Mongo.GetCollection(repo.CollectionBillPurchase)
+		_, err := updateBilltoStage(c, bill.PlanId, idStatges, apictx, db)
 		if err != nil {
 			return nil, errors.New("该单据改动同步到产品失败")
 		}

+ 36 - 11
boxcost/api/plan.go

@@ -20,6 +20,7 @@ import (
 	"github.com/xuri/excelize/v2"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo"
 )
 
 // TODO 下载代码重复提取
@@ -183,7 +184,7 @@ type UpdateBilltoStageReq struct {
 }
 
 // 更新供应商确定数量与plan中stage项的同步
-func updateBilltoStage(c *gin.Context, planId primitive.ObjectID, idStatges map[string]*UpdateBilltoStageReq, apictx *ApiSession) (interface{}, error) {
+func updateBilltoStage(c *gin.Context, planId primitive.ObjectID, idStatges map[string]*UpdateBilltoStageReq, apictx *ApiSession, db *mongo.Collection) (interface{}, error) {
 	if len(idStatges) == 0 {
 		return true, nil
 	}
@@ -221,19 +222,43 @@ func updateBilltoStage(c *gin.Context, planId primitive.ObjectID, idStatges map[
 				stage.Size = idStatge.Size
 				stage.UpdateTime = time.Now()
 				fmt.Printf("stage信息:%#v\n", stage)
+
+				// 更新stage
+				req := StageRequest{
+					PlanId:  planId.Hex(),
+					CompId:  comp.Id,
+					StageId: stage.Id,
+					Stages:  []*model.ComponentStage{stage},
+				}
+				_, err = updateStage(c, db, &req)
+				if err != nil {
+					return nil, err
+				}
+				// 更新计划价格
+				err := updatePrices(c, db, planId, comp.Id)
+				if err != nil {
+					return nil, err
+				}
+				// 记录历史
+				_, err = AddPlanHistory(c, apictx, req.PlanId, "sync")
+				if err != nil {
+					fmt.Println("记录历史失败:", err)
+				}
+				return true, nil
 			}
 		}
 	}
-	plan.UpdateTime = time.Now()
-	userId, _ := primitive.ObjectIDFromHex(apictx.User.ID)
-	user, _ := getUserById(apictx, userId)
-	// return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionProductPlan, planId.Hex(), &plan)
-	return repo.RepoUpdateSetDoc1(apictx.CreateRepoCtx(), repo.CollectionProductPlan, planId.Hex(), &plan, &repo.RecordLogReq{
-		Path:     c.Request.URL.Path,
-		UserInfo: user,
-		TargetId: planId.Hex(),
-		Type:     "sync",
-	})
+	return true, nil
+	// plan.UpdateTime = time.Now()
+	// userId, _ := primitive.ObjectIDFromHex(apictx.User.ID)
+	// user, _ := getUserById(apictx, userId)
+	// // return repo.RepoUpdateSetDoc(apictx.CreateRepoCtx(), repo.CollectionProductPlan, planId.Hex(), &plan)
+	// return repo.RepoUpdateSetDoc1(apictx.CreateRepoCtx(), repo.CollectionProductPlan, planId.Hex(), &plan, &repo.RecordLogReq{
+	// 	Path:     c.Request.URL.Path,
+	// 	UserInfo: user,
+	// 	TargetId: planId.Hex(),
+	// 	Type:     "sync",
+	// })
 }
 
 // 更新供应商确定数量与plan中stage项的同步

+ 2 - 2
boxcost/api/router.go

@@ -74,9 +74,9 @@ func RegRouters(svc *Service) {
 	// plan相关操作
 	boxcost.POSTJWT("/plan/add/component/:id", AddCompnonet)
 	boxcost.POSTJWT("/plan/delete/component/:id/:componentId", DeleteCompnonet)
-	boxcost.POSTJWT("/plan/update/componentName/:id/:componentId", UpdateCompnonetName)
+	boxcost.POSTJWT("/plan/update/component/:id/:componentId", UpdateCompnonet)
 	boxcost.POSTJWT("/plan/add/stages", AddStage)
-	boxcost.POSTJWT("/plan/update/stages", UpdateStage)
+	boxcost.POSTJWT("/plan/update/stages", UpdateStages)
 	boxcost.POSTJWT("/plan/delete/stage", DeleteStage)
 	boxcost.POSTJWT("/plan/update/fileds", UpdatePlanfileds)
 

+ 118 - 30
boxcost/api/stages.go

@@ -3,7 +3,6 @@ package api
 import (
 	"box-cost/db/model"
 	"box-cost/db/repo"
-	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
@@ -18,18 +17,18 @@ import (
 
 // StageRequest 用于添加和更新stage的请求结构
 type StageRequest struct {
-	PlanId  string                  `json:"planId"`
-	PackId  string                  `json:"packId"`
+	PlanId string `json:"planId"`
+	// PackId  string                  `json:"packId"`
 	CompId  string                  `json:"componentId"`
 	StageId string                  `json:"stageId,omitempty"`
 	Stages  []*model.ComponentStage `json:"stages"`
 }
 
 // 更新计划和部件的价格
-func updatePrices(ctx context.Context, db *mongo.Collection, planId primitive.ObjectID, compId string) error {
+func updatePrices(c *gin.Context, db *mongo.Collection, planId primitive.ObjectID, compId string) error {
 	// 1. 获取计划详情
 	var plan model.ProductPlan
-	err := db.FindOne(ctx, bson.M{"_id": planId}).Decode(&plan)
+	err := db.FindOne(c.Request.Context(), bson.M{"_id": planId}).Decode(&plan)
 	if err != nil {
 		return err
 	}
@@ -45,7 +44,7 @@ func updatePrices(ctx context.Context, db *mongo.Collection, planId primitive.Ob
 		}
 		// 更新组件总价
 		if comp.Id == compId {
-			_, err = db.UpdateOne(ctx,
+			_, err = db.UpdateOne(c.Request.Context(),
 				bson.M{"_id": planId, "pack.components.id": compId},
 				bson.M{"$set": bson.M{"pack.components.$.totalPrice": compPrice}})
 			if err != nil {
@@ -56,7 +55,7 @@ func updatePrices(ctx context.Context, db *mongo.Collection, planId primitive.Ob
 	}
 
 	// 3. 更新计划总价
-	_, err = db.UpdateOne(ctx,
+	_, err = db.UpdateOne(c.Request.Context(),
 		bson.M{"_id": planId},
 		bson.M{"$set": bson.M{"totalPrice": &totalPrice}})
 	return err
@@ -96,7 +95,7 @@ func AddStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	})
 	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
 
-	result, err := db.UpdateOne(apictx.CreateRepoCtx().Ctx,
+	result, err := db.UpdateOne(c.Request.Context(),
 		bson.M{"_id": planId},
 		update,
 		opts,
@@ -107,7 +106,7 @@ func AddStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 
 	// 更新价格
-	err = updatePrices(apictx.CreateRepoCtx().Ctx, db, planId, req.CompId)
+	err = updatePrices(c, db, planId, req.CompId)
 	if err != nil {
 		return nil, err
 	}
@@ -153,7 +152,7 @@ func DeleteStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 		Filters: arrayFilters,
 	})
 
-	result, err := db.UpdateOne(apictx.CreateRepoCtx().Ctx,
+	result, err := db.UpdateOne(c.Request.Context(),
 		bson.M{"_id": planId},
 		update,
 		opts,
@@ -164,7 +163,7 @@ func DeleteStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 
 	// 更新价格
-	err = updatePrices(apictx.CreateRepoCtx().Ctx, db, planId, req.CompId)
+	err = updatePrices(c, db, planId, req.CompId)
 	if err != nil {
 		return nil, err
 	}
@@ -177,10 +176,68 @@ func DeleteStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	return result, nil
 }
 
+// 根据planId packId compentId stageId定位到到计划中的stage
+// 注意更新计划价格 组件价格
+// 根据planId packId compentId stageId定位到到计划中的stage
+// 注意更新计划价格 组件价格
+func updateStage(c *gin.Context, db *mongo.Collection, req *StageRequest) (interface{}, error) {
+	if len(req.PlanId) == 0 || len(req.CompId) == 0 || len(req.StageId) == 0 {
+		return nil, fmt.Errorf("planId, componentId and stageId are required")
+	}
+
+	planId, err := primitive.ObjectIDFromHex(req.PlanId)
+	if err != nil {
+		return nil, fmt.Errorf("invalid planId: %v", err)
+	}
+
+	// 构建更新
+	update := bson.M{
+		"$set": bson.M{
+			"pack.components.$[components].stages.$[stage]": req.Stages[0],
+			"updateTime": time.Now(),
+		},
+	}
+
+	// 设置数组过滤器
+	arrayFilters := options.ArrayFilters{
+		Filters: []interface{}{
+			bson.M{"components.id": req.CompId},
+			bson.M{"stage.id": req.StageId},
+		},
+	}
+
+	// 执行更新
+	opts := options.FindOneAndUpdate().
+		SetArrayFilters(arrayFilters).
+		SetReturnDocument(options.After)
+
+	result := db.FindOneAndUpdate(
+		c.Request.Context(),
+		bson.M{"_id": planId},
+		update,
+		opts,
+	)
+
+	if result.Err() != nil {
+		if result.Err() == mongo.ErrNoDocuments {
+			return nil, fmt.Errorf("plan or stage not found")
+		}
+		return nil, fmt.Errorf("failed to update stage: %v", result.Err())
+	}
+
+	// 更新价格
+	err = updatePrices(c, db, planId, req.CompId)
+	if err != nil {
+		return nil, fmt.Errorf("failed to update prices: %v", err)
+	}
+
+	return true, nil
+}
+
 // 更新stages
 // 根据planId packId compentId stageId定位到到计划中的stage
 // 注意更新计划价格 组件价格
-func UpdateStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+func UpdateStages(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	var req StageRequest
 	if err := c.ShouldBindJSON(&req); err != nil {
 		return nil, err
@@ -198,8 +255,10 @@ func UpdateStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 
 	// 获取更新前的数据用于验证
 	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
+	ctx := c.Request.Context()
+
 	var plan model.ProductPlan
-	err = db.FindOne(apictx.CreateRepoCtx().Ctx, bson.M{"_id": planId}).Decode(&plan)
+	err = db.FindOne(ctx, bson.M{"_id": planId}).Decode(&plan)
 	if err != nil {
 		return nil, fmt.Errorf("failed to find plan: %v", err)
 	}
@@ -255,13 +314,13 @@ func UpdateStage(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 
 	// 执行批量更新
 	opts := options.BulkWrite().SetOrdered(false) // 允许并行执行
-	result, err := db.BulkWrite(apictx.CreateRepoCtx().Ctx, models, opts)
+	result, err := db.BulkWrite(c.Request.Context(), models, opts)
 	if err != nil {
 		return nil, fmt.Errorf("failed to update stages: %v", err)
 	}
 
 	// 更新价格
-	err = updatePrices(apictx.CreateRepoCtx().Ctx, db, planId, req.CompId)
+	err = updatePrices(c, db, planId, req.CompId)
 	if err != nil {
 		return nil, fmt.Errorf("failed to update prices: %v", err)
 	}
@@ -297,6 +356,7 @@ func UpdatePlanfileds(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 		Total:      req.Total,
 		CreateUser: req.CreateUser,
 		Name:       req.Name,
+		UpdateTime: time.Now(),
 	})
 	if err != nil {
 		return nil, err
@@ -328,7 +388,7 @@ func AddCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	newTotalPrice := component.TotalPrice
 	oldPlan := &model.ProductPlan{}
 	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
-	if err := db.FindOne(c, bson.M{"_id": planId}).Decode(&oldPlan); err != nil {
+	if err := db.FindOne(c.Request.Context(), bson.M{"_id": planId}).Decode(&oldPlan); err != nil {
 		return nil, err
 	} else if oldPlan.TotalPrice != nil {
 		newTotalPrice += *oldPlan.TotalPrice
@@ -347,7 +407,7 @@ func AddCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 
 	filter := bson.M{"_id": planId}
-	result := db.FindOneAndUpdate(c, filter, update)
+	result := db.FindOneAndUpdate(c.Request.Context(), filter, update)
 	if result.Err() != nil {
 		return nil, result.Err()
 	}
@@ -376,7 +436,7 @@ func DeleteCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	// Find the component to be deleted and its price
 	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
 	var componentPrice float64
-	if err := db.FindOne(c, bson.M{"_id": planId}).Decode(&oldPlan); err != nil {
+	if err := db.FindOne(c.Request.Context(), bson.M{"_id": planId}).Decode(&oldPlan); err != nil {
 		return nil, err
 	} else if oldPlan.Pack != nil {
 		for _, comp := range oldPlan.Pack.Components {
@@ -409,7 +469,7 @@ func DeleteCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	}
 
 	filter := bson.M{"_id": planId}
-	result := db.FindOneAndUpdate(c, filter, update)
+	result := db.FindOneAndUpdate(c.Request.Context(), filter, update)
 	if result.Err() != nil {
 		return nil, result.Err()
 	}
@@ -422,7 +482,12 @@ func DeleteCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	return true, nil
 }
 
-func UpdateCompnonetName(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+type UpdateCompnonetReq struct {
+	Name   string                  `json:"name,omitempty"`
+	Stages []*model.ComponentStage `json:"stages,omitempty"`
+}
+
+func UpdateCompnonet(c *gin.Context, apictx *ApiSession) (interface{}, error) {
 	_planId := c.Param("id")
 	planId, _ := primitive.ObjectIDFromHex(_planId)
 	if planId.IsZero() {
@@ -433,31 +498,50 @@ func UpdateCompnonetName(c *gin.Context, apictx *ApiSession) (interface{}, error
 		return nil, fmt.Errorf("componentId is invalid")
 	}
 
-	var nameUpdate struct {
-		Name string `json:"name"`
-	}
+	var nameUpdate UpdateCompnonetReq
 	if err := c.ShouldBindJSON(&nameUpdate); err != nil {
 		return nil, err
 	}
 
+	// 检查是否有需要更新的字段
+	if len(nameUpdate.Name) == 0 && len(nameUpdate.Stages) == 0 {
+		return nil, fmt.Errorf("no fields to update")
+	}
+
+	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
 	update := bson.M{
 		"$set": bson.M{
-			"pack.components.$.name": nameUpdate.Name,
-			"updateTime":             time.Now(),
+			"updateTime": time.Now(),
 		},
 	}
 
+	if len(nameUpdate.Name) > 0 {
+		update["$set"].(bson.M)["pack.components.$.name"] = nameUpdate.Name
+	}
+
+	if len(nameUpdate.Stages) > 0 {
+		update["$set"].(bson.M)["pack.components.$.stages"] = nameUpdate.Stages
+	}
+
 	filter := bson.M{
 		"_id":                planId,
 		"pack.components.id": componentId,
 	}
-	db := apictx.Svc.Mongo.GetCollection(repo.CollectionProductPlan)
-	result := db.FindOneAndUpdate(c, filter, update)
+
+	result := db.FindOneAndUpdate(c.Request.Context(), filter, update)
 	if result.Err() != nil {
 		return nil, result.Err()
 	}
 
-	// 获取更新后的数据并记录历史
+	// 如果更新了stages,需要更新价格
+	if len(nameUpdate.Stages) > 0 {
+		err := updatePrices(c, db, planId, componentId)
+		if err != nil {
+			return nil, fmt.Errorf("failed to update prices: %v", err)
+		}
+	}
+
+	// 记录历史
 	_, err := AddPlanHistory(c, apictx, _planId)
 	if err != nil {
 		fmt.Println("记录历史失败:", err)
@@ -467,7 +551,11 @@ func UpdateCompnonetName(c *gin.Context, apictx *ApiSession) (interface{}, error
 }
 
 // 记录历史
-func AddPlanHistory(c *gin.Context, apictx *ApiSession, planId string) (interface{}, error) {
+func AddPlanHistory(c *gin.Context, apictx *ApiSession, planId string, ht ...string) (interface{}, error) {
+	htype := "update"
+	if len(ht) > 0 {
+		htype = ht[0]
+	}
 	// 获取更新后的数据并记录历史
 	newPlan := &model.ProductPlan{}
 	found, err := repo.RepoSeachDoc(apictx.CreateRepoCtx(), &repo.DocSearchOptions{
@@ -493,7 +581,7 @@ func AddPlanHistory(c *gin.Context, apictx *ApiSession, planId string) (interfac
 		TargetId:   planId,
 		Path:       c.Request.URL.Path,
 		Collection: repo.CollectionProductPlan,
-		Type:       "update",
+		Type:       htype,
 		Content:    string(newPlanBytes),
 		CreateTime: time.Now(),
 	}

+ 1 - 1
comm

@@ -1 +1 @@
-Subproject commit 03721d7b9d3dd23b9cffdf9388845c89ace40049
+Subproject commit f4266e04a734dc123c65dd48e8fc30a51a92b9e0