From fbfdedb3edb610d496eb81381b372bd581d06499 Mon Sep 17 00:00:00 2001 From: zetaloop Date: Thu, 23 Apr 2026 16:59:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=A4=8D=E5=90=88=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E8=A1=A8=20shop=5Fplayers=20=E7=9A=84=20update=20=E6=94=B9?= =?UTF-8?q?=E7=94=A8=E5=8E=9F=E7=94=9F=20SQL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ent 的 Update().Where() 对复合主键表会报 "sql/sqlgraph: invalid composite id for update table",这是 ent 框架已知的限制(field.ID 复合主键仅对 edge schema 完整支持)。同表的 Create/Delete/Query 操作不受影响,仅 Update 需要绕过。在 ServiceContext 中暴露底层 *sql.DB 以供 ExecContext 执行原生 SQL。 --- .../internal/logic/updateShopPlayersLogic.go | 25 ++++++++++--------- app/shop/rpc/internal/svc/serviceContext.go | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/shop/rpc/internal/logic/updateShopPlayersLogic.go b/app/shop/rpc/internal/logic/updateShopPlayersLogic.go index d0c6650..1528083 100644 --- a/app/shop/rpc/internal/logic/updateShopPlayersLogic.go +++ b/app/shop/rpc/internal/logic/updateShopPlayersLogic.go @@ -3,8 +3,6 @@ package logic import ( "context" "errors" - "juwan-backend/app/shop/rpc/internal/models/predicate" - "juwan-backend/app/shop/rpc/internal/models/shopplayers" "time" "juwan-backend/app/shop/rpc/internal/svc" @@ -32,25 +30,28 @@ func (l *UpdateShopPlayersLogic) UpdateShopPlayers(in *pb.UpdateShopPlayersReq) return nil, errors.New("invalid shop_id or player_id") } - preds := []predicate.ShopPlayers{ - shopplayers.ShopIDEQ(in.ShopId), - shopplayers.PlayerIDEQ(in.PlayerId), - } - - updater := l.svcCtx.ShopModelRW.ShopPlayers.Update(). - Where(shopplayers.And(preds...)). - SetIsPrimary(in.IsPrimary) + // ent 的 Update().Where() 不支持复合主键表(shop_players 的主键是 (shop_id, player_id)), + // 会报 "sql/sqlgraph: invalid composite id for update table"。 + // Create/Delete/Query 不受影响,仅 Update 需要走原生 SQL。 + query := `UPDATE shop_players SET is_primary = $1, left_at = $2 WHERE shop_id = $3 AND player_id = $4` + var leftAt *time.Time if in.LeftAt > 0 { t := time.Unix(in.LeftAt, 0) - updater = updater.SetLeftAt(t) + leftAt = &t } - affected, err := updater.Save(l.ctx) + result, err := l.svcCtx.DBRW.ExecContext(l.ctx, query, in.IsPrimary, leftAt, in.ShopId, in.PlayerId) if err != nil { logx.Errorf("update shop players failed, %s", err.Error()) return nil, errors.New("update shop players failed") } + + affected, err := result.RowsAffected() + if err != nil { + logx.Errorf("get rows affected failed, %s", err.Error()) + return nil, errors.New("update shop players failed") + } if affected == 0 { return nil, errors.New("shop player not found") } diff --git a/app/shop/rpc/internal/svc/serviceContext.go b/app/shop/rpc/internal/svc/serviceContext.go index e2b6708..bcbd829 100644 --- a/app/shop/rpc/internal/svc/serviceContext.go +++ b/app/shop/rpc/internal/svc/serviceContext.go @@ -27,6 +27,7 @@ type ServiceContext struct { UsersRpc usercenter.Usercenter ShopModelRW *models.Client ShopModelRO *models.Client + DBRW *stdsql.DB } func NewServiceContext(c config.Config) *ServiceContext { @@ -68,5 +69,6 @@ func NewServiceContext(c config.Config) *ServiceContext { UsersRpc: usercenter.NewUsercenter(zrpc.MustNewClient(c.UsersRpcConf)), ShopModelRO: models.NewClient(roModelOpts...), ShopModelRW: models.NewClient(rwModelOpts...), + DBRW: rawRW, } }