فهرست منبع

Merge branch 'dev/v1.1.20_fuwencai' of http://192.168.3.207:8080/BaseService/jyMicroservices into dev/v1.1.20_fuwencai

fuwencai 2 سال پیش
والد
کامیت
e07dc3b5ca

+ 1 - 0
jyBXCore/api/internal/logic/participateActionLogic.go

@@ -38,6 +38,7 @@ func (l *ParticipateActionLogic) ParticipateAction(req *types.ParticipateActionR
 		AccountId:    req.AccountId,
 		UserId:       req.UserId,
 		NewUserId:    req.NewUserId,
+		ProjectIds:   req.ProjectIds,
 		BidId:        req.BidId,
 		ToEntUserId:  req.ToEntUserId,
 		IsRetain:     req.IsRetain,

+ 3 - 3
jyBXCore/api/internal/svc/serviceContext.go

@@ -3,17 +3,17 @@ package svc
 import (
 	"github.com/zeromicro/go-zero/zrpc"
 	"jyBXCore/api/internal/config"
-	"jyBXCore/rpc/bxcoreclient"
+	"jyBXCore/rpc/bxcore"
 )
 
 type ServiceContext struct {
 	Config config.Config
-	BxCore bxcoreclient.BxCore
+	BxCore bxcore.BxCore
 }
 
 func NewServiceContext(c config.Config) *ServiceContext {
 	return &ServiceContext{
 		Config: c,
-		BxCore: bxcoreclient.NewBxCore(zrpc.MustNewClient(c.Core)),
+		BxCore: bxcore.NewBxCore(zrpc.MustNewClient(c.Core)),
 	}
 }

+ 0 - 154
jyBXCore/rpc/bxcoreclient/bxcore.go

@@ -1,154 +0,0 @@
-// Code generated by goctl. DO NOT EDIT!
-// Source: bxcore.proto
-
-package bxcoreclient
-
-import (
-	"context"
-
-	"jyBXCore/rpc/type/bxcore"
-
-	"github.com/zeromicro/go-zero/zrpc"
-	"google.golang.org/grpc"
-)
-
-type (
-	BidTypeReq                 = bxcore.BidTypeReq
-	PInfo                      = bxcore.PInfo
-	ParticipateActionReq       = bxcore.ParticipateActionReq
-	ParticipateActionRes       = bxcore.ParticipateActionRes
-	ParticipateContentData     = bxcore.ParticipateContentData
-	ParticipateContentReq      = bxcore.ParticipateContentReq
-	ParticipateContentRes      = bxcore.ParticipateContentRes
-	ParticipateData            = bxcore.ParticipateData
-	ParticipateDetailInfo      = bxcore.ParticipateDetailInfo
-	ParticipateInfoReq         = bxcore.ParticipateInfoReq
-	ParticipateInfoRes         = bxcore.ParticipateInfoRes
-	ParticipateList            = bxcore.ParticipateList
-	ParticipateListReq         = bxcore.ParticipateListReq
-	ParticipateListRes         = bxcore.ParticipateListRes
-	ParticipatePerson          = bxcore.ParticipatePerson
-	ParticipatePersonsReq      = bxcore.ParticipatePersonsReq
-	ParticipatePersonsRes      = bxcore.ParticipatePersonsRes
-	ParticipateRecords         = bxcore.ParticipateRecords
-	ParticipateRecordsReq      = bxcore.ParticipateRecordsReq
-	ParticipateRecordsRes      = bxcore.ParticipateRecordsRes
-	ParticipateRecordsRes_Data = bxcore.ParticipateRecordsRes_Data
-	ParticipateSetUpInfo       = bxcore.ParticipateSetUpInfo
-	ParticipateSetUpInfoReq    = bxcore.ParticipateSetUpInfoReq
-	ParticipateSetUpInfoRes    = bxcore.ParticipateSetUpInfoRes
-	ParticipateShowReq         = bxcore.ParticipateShowReq
-	ParticipateShowRes         = bxcore.ParticipateShowRes
-	RemindRuleReq              = bxcore.RemindRuleReq
-	SearchData                 = bxcore.SearchData
-	SearchLimitReq             = bxcore.SearchLimitReq
-	SearchLimitResp            = bxcore.SearchLimitResp
-	SearchList                 = bxcore.SearchList
-	SearchReq                  = bxcore.SearchReq
-	SearchResp                 = bxcore.SearchResp
-	ShowInfo                   = bxcore.ShowInfo
-	UpdateBidStatusReq         = bxcore.UpdateBidStatusReq
-	UpdateBidStatusRes         = bxcore.UpdateBidStatusRes
-	WinnerInfo                 = bxcore.WinnerInfo
-
-	BxCore interface {
-		// 标讯搜索结果列表数据
-		GetSearchList(ctx context.Context, in *SearchReq, opts ...grpc.CallOption) (*SearchResp, error)
-		// 标讯搜索限制内容
-		SearchLimit(ctx context.Context, in *SearchLimitReq, opts ...grpc.CallOption) (*SearchLimitResp, error)
-		//  列表数据参标信息接口
-		ParticipateShow(ctx context.Context, in *ParticipateShowReq, opts ...grpc.CallOption) (*ParticipateShowRes, error)
-		//  详情页参标信息接口
-		ParticipateInfo(ctx context.Context, in *ParticipateInfoReq, opts ...grpc.CallOption) (*ParticipateInfoRes, error)
-		//   投标状态更新
-		UpdateBidStatus(ctx context.Context, in *UpdateBidStatusReq, opts ...grpc.CallOption) (*UpdateBidStatusRes, error)
-		//  获取投标状态信息
-		ParticipateContent(ctx context.Context, in *ParticipateContentReq, opts ...grpc.CallOption) (*ParticipateContentRes, error)
-		//  参标操作记录
-		ParticipateRecords(ctx context.Context, in *ParticipateRecordsReq, opts ...grpc.CallOption) (*ParticipateRecordsRes, error)
-		//  当前部门/企业下参标人员信息
-		ParticipatePersons(ctx context.Context, in *ParticipatePersonsReq, opts ...grpc.CallOption) (*ParticipatePersonsRes, error)
-		//  参标设置信息
-		ParticipateSetUpInfo(ctx context.Context, in *ParticipateSetUpInfoReq, opts ...grpc.CallOption) (*ParticipateSetUpInfoRes, error)
-		//  项目参标 终止参标 划转等动作
-		ParticipateAction(ctx context.Context, in *ParticipateActionReq, opts ...grpc.CallOption) (*ParticipateActionRes, error)
-		//  我的参标项目列表|企业参标项目列表
-		ParticipateList(ctx context.Context, in *ParticipateListReq, opts ...grpc.CallOption) (*ParticipateListRes, error)
-	}
-
-	defaultBxCore struct {
-		cli zrpc.Client
-	}
-)
-
-func NewBxCore(cli zrpc.Client) BxCore {
-	return &defaultBxCore{
-		cli: cli,
-	}
-}
-
-// 标讯搜索结果列表数据
-func (m *defaultBxCore) GetSearchList(ctx context.Context, in *SearchReq, opts ...grpc.CallOption) (*SearchResp, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.GetSearchList(ctx, in, opts...)
-}
-
-// 标讯搜索限制内容
-func (m *defaultBxCore) SearchLimit(ctx context.Context, in *SearchLimitReq, opts ...grpc.CallOption) (*SearchLimitResp, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.SearchLimit(ctx, in, opts...)
-}
-
-//  列表数据参标信息接口
-func (m *defaultBxCore) ParticipateShow(ctx context.Context, in *ParticipateShowReq, opts ...grpc.CallOption) (*ParticipateShowRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateShow(ctx, in, opts...)
-}
-
-//  详情页参标信息接口
-func (m *defaultBxCore) ParticipateInfo(ctx context.Context, in *ParticipateInfoReq, opts ...grpc.CallOption) (*ParticipateInfoRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateInfo(ctx, in, opts...)
-}
-
-//   投标状态更新
-func (m *defaultBxCore) UpdateBidStatus(ctx context.Context, in *UpdateBidStatusReq, opts ...grpc.CallOption) (*UpdateBidStatusRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.UpdateBidStatus(ctx, in, opts...)
-}
-
-//  获取投标状态信息
-func (m *defaultBxCore) ParticipateContent(ctx context.Context, in *ParticipateContentReq, opts ...grpc.CallOption) (*ParticipateContentRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateContent(ctx, in, opts...)
-}
-
-//  参标操作记录
-func (m *defaultBxCore) ParticipateRecords(ctx context.Context, in *ParticipateRecordsReq, opts ...grpc.CallOption) (*ParticipateRecordsRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateRecords(ctx, in, opts...)
-}
-
-//  当前部门/企业下参标人员信息
-func (m *defaultBxCore) ParticipatePersons(ctx context.Context, in *ParticipatePersonsReq, opts ...grpc.CallOption) (*ParticipatePersonsRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipatePersons(ctx, in, opts...)
-}
-
-//  参标设置信息
-func (m *defaultBxCore) ParticipateSetUpInfo(ctx context.Context, in *ParticipateSetUpInfoReq, opts ...grpc.CallOption) (*ParticipateSetUpInfoRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateSetUpInfo(ctx, in, opts...)
-}
-
-//  项目参标 终止参标 划转等动作
-func (m *defaultBxCore) ParticipateAction(ctx context.Context, in *ParticipateActionReq, opts ...grpc.CallOption) (*ParticipateActionRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateAction(ctx, in, opts...)
-}
-
-//  我的参标项目列表|企业参标项目列表
-func (m *defaultBxCore) ParticipateList(ctx context.Context, in *ParticipateListReq, opts ...grpc.CallOption) (*ParticipateListRes, error) {
-	client := bxcore.NewBxCoreClient(m.cli.Conn())
-	return client.ParticipateList(ctx, in, opts...)
-}

+ 26 - 21
jyBXCore/rpc/model/tidb/tidb.go

@@ -8,6 +8,7 @@ import (
 	"fmt"
 	"github.com/zeromicro/go-zero/core/logx"
 	IC "jyBXCore/rpc/init"
+	"jyBXCore/rpc/model/es"
 	"jyBXCore/rpc/type/bxcore"
 	"strconv"
 	"strings"
@@ -23,7 +24,7 @@ var (
 )
 
 //划转参标信息
-func TransferParticipateInfo(in *bxcore.ParticipateActionReq) error {
+func TransferParticipateInfo(projectId string, in *bxcore.ParticipateActionReq) error {
 	defer MC.Catch()
 	//保存或更新新跟踪人
 	if !IC.BaseMysql.ExecTx("划转参标信息", func(tx *sql.Tx) bool {
@@ -38,7 +39,7 @@ func TransferParticipateInfo(in *bxcore.ParticipateActionReq) error {
 		//是否保留原参标人
 		if !in.IsRetain {
 			//不保留 原参标人,获取把原参标人信息
-			partInfo := IC.BaseMysql.SelectBySqlByTx(tx, "SELECT id,position_id FROM `participate_user` WHERE  project_id = ?  AND ent_id = ? AND state > -1", in.BidId, in.EntId)
+			partInfo := IC.BaseMysql.SelectBySqlByTx(tx, "SELECT id,position_id FROM `participate_user` WHERE  project_id = ?  AND ent_id = ? AND state > -1", projectId, in.EntId)
 			if partInfo != nil && len(*partInfo) > 0 {
 				for _, v := range *partInfo {
 					ids = append(ids, MC.IntAll(v["id"]))
@@ -47,7 +48,7 @@ func TransferParticipateInfo(in *bxcore.ParticipateActionReq) error {
 					fromUserNames = append(fromUserNames, userInfo.EntUserName)
 				}
 			}
-			b1 = IC.BaseMysql.UpdateOrDeleteBySqlByTx(tx, fmt.Sprintf(`UPDATE participate_user SET state = -2 ,update_date = %s WHERE ent_id = ? AND project_id = ?`, date.FormatDate(&now, date.Date_Full_Layout)), in.EntId, in.BidId) > 0
+			b1 = IC.BaseMysql.UpdateOrDeleteBySqlByTx(tx, fmt.Sprintf(`UPDATE participate_user SET state = -2 ,update_date = %s WHERE ent_id = ? AND project_id = ?`, date.FormatDate(&now, date.Date_Full_Layout)), in.EntId, projectId) > 0
 		}
 		//查询划转人信息
 		entUserId, _ := strconv.ParseInt(in.ToEntUserId, 10, 64)
@@ -60,20 +61,20 @@ func TransferParticipateInfo(in *bxcore.ParticipateActionReq) error {
 			"ent_id":         in.EntId,
 			"ent_user_id":    entUserId,
 			"position_id":    positionId,
-			"project_id":     in.BidId,
+			"project_id":     projectId,
 			"record_content": content,
 			"create_date":    date.FormatDate(&now, date.Date_Full_Layout),
 		}) > 0
 		return b1 && b2 && b3
 	}) {
-		logx.Info(in.PositionId, "---终止---", in.BidId)
+		logx.Info(in.PositionId, "---终止---", projectId)
 		return fmt.Errorf("终止参标更新信息出错")
 	}
 	return nil
 }
 
 //终止参标
-func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error {
+func CancelParticipateInfo(projectId string, in *bxcore.ParticipateActionReq, roleId int64) error {
 	defer MC.Catch()
 	if !IC.BaseMysql.ExecTx("终止参标", func(tx *sql.Tx) bool {
 		var (
@@ -83,7 +84,7 @@ func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error
 		)
 		//管理员终止:当前项目 其他参标人也被终止
 		query := map[string]interface{}{
-			"project_id": in.BidId,
+			"project_id": projectId,
 			"ent_id":     in.EntId,
 		}
 		//个人终止:仅仅终止本人参标项目
@@ -102,31 +103,31 @@ func CancelParticipateInfo(in *bxcore.ParticipateActionReq, roleId int64) error
 			"ent_id":         in.EntId,
 			"ent_user_id":    in.EntUserId,
 			"position_id":    in.PositionId,
-			"project_id":     in.BidId,
+			"project_id":     projectId,
 			"record_content": tip,
 			"create_date":    date.FormatDate(&now, date.Date_Full_Layout),
 		}) > 0
 		return b1 && b2
 	}) {
-		logx.Info(in.PositionId, "---终止---", in.BidId)
+		logx.Info(in.PositionId, "---终止---", projectId)
 		return fmt.Errorf("终止参标更新信息出错")
 	}
 	return nil
 }
 
 //保存参标信息
-func SaveParticipateInfo(in *bxcore.ParticipateActionReq) error {
+func SaveParticipateInfo(projectId string, in *bxcore.ParticipateActionReq) error {
 	defer MC.Catch()
 	if !IC.BaseMysql.ExecTx("保存|更新参标信息及保存参标记录", func(tx *sql.Tx) bool {
 		var (
-			b1, b2 bool
-			now    = time.Now()
+			b1, b2, b3 bool
+			now        = time.Now()
 		)
 		//保存参标--participate_user
 		//查看是否参标过当前项目
-		if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM `participate_user` WHERE position_id = ? AND project_id = ?  AND ent_id = ?", in.PositionId, in.BidId, in.EntId); c > 0 {
+		if c := IC.BaseMysql.CountBySql("SELECT count(id) FROM `participate_user` WHERE position_id = ? AND project_id = ?  AND ent_id = ?", in.PositionId, projectId, in.EntId); c > 0 {
 			//更新
-			b1 = IC.BaseMysql.UpdateOrDeleteBySqlByTx(tx, fmt.Sprintf(`UPDATE participate_user SET state = 0 ,update_date = %s WHERE position_id = ? AND ent_id = ? AND project_id = ?`, date.FormatDate(&now, date.Date_Full_Layout)), in.PositionId, in.EntId, in.BidId) > 0
+			b1 = IC.BaseMysql.UpdateOrDeleteBySqlByTx(tx, fmt.Sprintf(`UPDATE participate_user SET state = 0 ,update_date = %s WHERE position_id = ? AND ent_id = ? AND project_id = ?`, date.FormatDate(&now, date.Date_Full_Layout)), in.PositionId, in.EntId, projectId) > 0
 		} else {
 			//保存
 			b1 = IC.BaseMysql.InsertByTx(tx, "participate_user", map[string]interface{}{
@@ -144,11 +145,14 @@ func SaveParticipateInfo(in *bxcore.ParticipateActionReq) error {
 			"ent_id":         in.EntId,
 			"ent_user_id":    in.EntUserId,
 			"position_id":    in.PositionId,
-			"project_id":     in.BidId,
+			"project_id":     projectId,
 			"record_content": "参标",
 			"create_date":    date.FormatDate(&now, date.Date_Full_Layout),
 		}) > 0
-		return b1 && b2
+		//保存或更新项目信息
+		//有问题 其他回滚,项目信息不用回滚
+		b3 = UpdateProjectInfo(projectId, es.GetProjectInfo(projectId), es.GetBiddingInfo(in.BidId)) == nil
+		return b1 && b2 && b3
 	}) {
 		logx.Info(in.PositionId, "---保存---", in.BidId)
 		return fmt.Errorf("保存参标信息出错")
@@ -161,9 +165,9 @@ func IsParticipatedByBidId(in *bxcore.ParticipateActionReq) bool {
 	defer MC.Catch()
 	//如果不允许多人参标 当前项目是否已经有企业其他人员参标
 	query := fmt.Sprintf(`SELECT count(id) FROM participate_user WHERE %s AND project_id = %s AND state >-1`, "%s", in.BidId)
-	if in.PositionType > 0 {
+	if in.PositionType > 0 { //企业版
 		query = fmt.Sprintf(query, fmt.Sprintf("ent_id = %d", in.EntId))
-	} else {
+	} else { //个人版
 		query = fmt.Sprintf(query, fmt.Sprintf("position_id = %d", in.PositionId))
 	}
 	return IC.BaseMysql.CountBySql(query) > 0
@@ -285,7 +289,7 @@ func GetParticipateSetInfo(in *bxcore.ParticipateSetUpInfoReq) (*bxcore.Particip
 }
 
 //保存或更新tidb 项目信息
-func UpdateProjectInfo(id string, pInfo map[string]interface{}, bInfo map[string]interface{}) {
+func UpdateProjectInfo(id string, pInfo map[string]interface{}, bInfo map[string]interface{}) error {
 	//id 项目id
 	//name 项目名称
 	//area  省份
@@ -317,13 +321,14 @@ func UpdateProjectInfo(id string, pInfo map[string]interface{}, bInfo map[string
 		if ok := IC.BaseMysql.Update("project", map[string]interface{}{
 			"id": id,
 		}, projectInfo); ok {
-			fmt.Errorf("项目信息更新异常", id)
+			return fmt.Errorf("项目信息更新异常", id)
 		}
 	} else {
 		if i := IC.BaseMysql.Insert("project", projectInfo); i <= 0 {
-			fmt.Errorf("项目信息插入异常", id)
+			return fmt.Errorf("项目信息插入异常", id)
 		}
 	}
+	return nil
 }
 
 // GetBidContentEnt 企业版 获取投标状态更新内容

+ 56 - 30
jyBXCore/rpc/service/participate.go

@@ -4,11 +4,13 @@ import (
 	MC "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/encrypt"
 	"fmt"
+	"github.com/zeromicro/go-zero/core/logx"
 	IC "jyBXCore/rpc/init"
 	"jyBXCore/rpc/model/es"
 	"jyBXCore/rpc/model/tidb"
 	"jyBXCore/rpc/type/bxcore"
 	"jyBXCore/rpc/util"
+	"strings"
 )
 
 //我的参标项目|企业参标项目 列表
@@ -36,38 +38,41 @@ func ParticipateList(in *bxcore.ParticipateListReq) (*bxcore.ParticipateListRes,
 //参标动作:参标、终止参标、划转:in:参标;out:终止参标;transfer:划转
 func ParticipateDo(in *bxcore.ParticipateActionReq) (*bxcore.ParticipateActionRes, error) {
 	defer MC.Catch()
-	//招标信息解密
-	in.BidId = encrypt.DecodeArticleId2ByCheck(in.BidId)[0]
-	if in.BidId == "" {
-		return nil, fmt.Errorf("当前招标信息有误")
-	}
-	bidId := in.BidId
-	//当前项目是否符合参标条件
-	projectInfos := es.GetProjectByInfoId([]string{in.BidId})
-	if projectInfos == nil || len(*projectInfos) == 0 {
-		tip := "参标"
-		switch in.ActionType {
-		case "out":
-			tip = "终止参标"
-		case "transfer":
-			tip = "划转"
-		}
-		return nil, fmt.Errorf(fmt.Sprintf("当前项目信息不满足%s条件", tip))
-	}
-	//符合参标项目id
-	projectInfo := (*projectInfos)[0]
-	if projectInfo["_id"] != nil && MC.ObjToString(projectInfo["_id"]) != "" {
-		in.BidId = MC.ObjToString(projectInfo["_id"])
-	} else {
-		return nil, fmt.Errorf("当前项目信息有误")
+	var (
+		tip = "参标"
+	)
+	switch in.ActionType {
+	case "out":
+		tip = "终止参标"
+	case "transfer":
+		tip = "划转"
 	}
-	//保存或更新项目信息
-	go tidb.UpdateProjectInfo(in.BidId, es.GetProjectInfo(in.BidId), es.GetBiddingInfo(bidId))
 	//企业版 判断是否是管理员
 	//判断用户身份
 	userInfo := IC.Middleground.PowerCheckCenter.Check(in.AppId, in.UserId, in.NewUserId, in.AccountId, in.EntId, in.PositionType, in.PositionId)
 	switch in.ActionType {
 	case "in":
+		var (
+			projectId = ""
+		)
+		//招标信息解密
+		in.BidId = encrypt.DecodeArticleId2ByCheck(in.BidId)[0]
+		if in.BidId == "" {
+			return nil, fmt.Errorf("当前招标信息有误")
+		}
+		//当前项目是否符合参标条件
+		projectInfos := es.GetProjectByInfoId([]string{in.BidId})
+		if projectInfos == nil || len(*projectInfos) == 0 {
+			return nil, fmt.Errorf(fmt.Sprintf("当前项目信息不满足%s条件", tip))
+		}
+		//符合参标项目id
+		projectInfo := (*projectInfos)[0]
+		if projectInfo["_id"] != nil && MC.ObjToString(projectInfo["_id"]) != "" {
+			//项目信息id
+			projectId = MC.ObjToString(projectInfo["_id"])
+		} else {
+			return nil, fmt.Errorf("当前项目信息有误")
+		}
 		//是否允许多人参标
 		if isAllow := util.IsALLow(in.EntId); !isAllow {
 			if ok := tidb.IsParticipatedByBidId(in); ok {
@@ -75,14 +80,26 @@ func ParticipateDo(in *bxcore.ParticipateActionReq) (*bxcore.ParticipateActionRe
 			}
 		}
 		//保存参标信息  更新当前企业参标项目记录
-		if err := tidb.SaveParticipateInfo(in); err != nil {
+		if err := tidb.SaveParticipateInfo(projectId, in); err != nil {
 			return nil, err
 		}
 	case "out": //终止参标
-		if err := tidb.CancelParticipateInfo(in, userInfo.Ent.EntRoleId); err != nil {
+		if len(strings.Split(in.ProjectIds, ",")) == 0 {
+			return nil, fmt.Errorf("项目信息有误")
+		}
+		projectId := strings.Split(in.ProjectIds, ",")[0]
+		//招标信息解密
+		projectId = encrypt.DecodeArticleId2ByCheck(projectId)[0]
+		if projectId == "" {
+			return nil, fmt.Errorf("当前项目信息有误")
+		}
+		if err := tidb.CancelParticipateInfo(projectId, in, userInfo.Ent.EntRoleId); err != nil {
 			return nil, err
 		}
 	case "transfer":
+		if len(strings.Split(in.ProjectIds, ",")) == 0 {
+			return nil, fmt.Errorf("项目信息有误")
+		}
 		//个人版
 		if in.PositionType == 0 {
 			return nil, fmt.Errorf("当前企业身份有误")
@@ -97,8 +114,17 @@ func ParticipateDo(in *bxcore.ParticipateActionReq) (*bxcore.ParticipateActionRe
 			//不允许多人参标,但是前端参数又是保留原参标人 互相矛盾
 			return nil, fmt.Errorf("当前项目只允许一人参标")
 		}
-		if err := tidb.TransferParticipateInfo(in); err != nil {
-			return nil, err
+		//in.ProjectIds //项目id
+		projectIds := strings.Split(in.ProjectIds, ",")
+		for _, v := range projectIds {
+			projectId := encrypt.DecodeArticleId2ByCheck(v)[0]
+			if projectId == "" {
+				continue
+			}
+			if err := tidb.TransferParticipateInfo(projectId, in); err != nil {
+				logx.Info(fmt.Sprintf("是否允许多人参标:%v, 项目id:%s,企业id:%d,划转对象entuserid:%s,划转异常:", isAllow, projectId, in.EntId, in.ToEntUserId))
+				continue
+			}
 		}
 	}
 	return &bxcore.ParticipateActionRes{