fix(customer_service): update EnsureExternalCustomer to use TxContext
This commit is contained in:
@@ -109,7 +109,7 @@ func (s *conversationService) Create(externalUser openidentity.ExternalUser, cha
|
|||||||
var conversation *models.Conversation
|
var conversation *models.Conversation
|
||||||
created := false
|
created := false
|
||||||
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
||||||
customerID, err := CustomerService.EnsureExternalCustomer(ctx.Tx, externalUser)
|
customerID, err := CustomerService.EnsureExternalCustomer(ctx, externalUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,14 +113,17 @@ func (s *customerService) CountByCompanyIDs(companyIDs []int64) map[int64]int64
|
|||||||
return repositories.CustomerRepository.CountByCompanyIDs(sqls.DB(), companyIDs, int(enums.StatusDeleted))
|
return repositories.CustomerRepository.CountByCompanyIDs(sqls.DB(), companyIDs, int(enums.StatusDeleted))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalUser openidentity.ExternalUser) (int64, error) {
|
func (s *customerService) EnsureExternalCustomer(ctx *sqls.TxContext, externalUser openidentity.ExternalUser) (int64, error) {
|
||||||
|
if ctx == nil || ctx.Tx == nil {
|
||||||
|
return 0, errorsx.InvalidParam("事务上下文不能为空")
|
||||||
|
}
|
||||||
externalSource := externalUser.ExternalSource
|
externalSource := externalUser.ExternalSource
|
||||||
externalID := strings.TrimSpace(externalUser.ExternalID)
|
externalID := strings.TrimSpace(externalUser.ExternalID)
|
||||||
if strings.TrimSpace(string(externalSource)) == "" || externalID == "" {
|
if strings.TrimSpace(string(externalSource)) == "" || externalID == "" {
|
||||||
return 0, errorsx.Unauthorized("外部用户标识不能为空")
|
return 0, errorsx.Unauthorized("外部用户标识不能为空")
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
if identity := repositories.CustomerIdentityRepository.GetBy(db, externalSource, externalID); identity != nil {
|
if identity := repositories.CustomerIdentityRepository.GetBy(ctx.Tx, externalSource, externalID); identity != nil {
|
||||||
updates := map[string]any{
|
updates := map[string]any{
|
||||||
"last_active_at": now,
|
"last_active_at": now,
|
||||||
"updated_at": now,
|
"updated_at": now,
|
||||||
@@ -128,14 +131,23 @@ func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalUser openi
|
|||||||
if strs.IsNotBlank(externalUser.ExternalName) {
|
if strs.IsNotBlank(externalUser.ExternalName) {
|
||||||
updates["name"] = externalUser.ExternalName
|
updates["name"] = externalUser.ExternalName
|
||||||
}
|
}
|
||||||
if err := repositories.CustomerRepository.Updates(db, identity.CustomerID, updates); err != nil {
|
if err := repositories.CustomerRepository.Updates(ctx.Tx, identity.CustomerID, updates); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if strs.IsNotBlank(externalUser.ExternalName) {
|
|
||||||
if err := s.syncConversationCustomerName(db, identity.CustomerID, externalUser.ExternalName, nil, now); err != nil {
|
ctx.RegisterCallback(func() {
|
||||||
return 0, err
|
go func() {
|
||||||
}
|
if strs.IsNotBlank(externalUser.ExternalName) {
|
||||||
}
|
if err := s.syncConversationCustomerName(sqls.DB(), identity.CustomerID, externalUser.ExternalName, nil, now); err != nil {
|
||||||
|
slog.Error("sync conversation customer name failed",
|
||||||
|
"customerId", identity.CustomerID,
|
||||||
|
"customerName", externalUser.ExternalName,
|
||||||
|
"error", err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
})
|
||||||
return identity.CustomerID, nil
|
return identity.CustomerID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,10 +157,10 @@ func (s *customerService) EnsureExternalCustomer(db *gorm.DB, externalUser openi
|
|||||||
Status: enums.StatusOk,
|
Status: enums.StatusOk,
|
||||||
AuditFields: utils.BuildAuditFields(nil),
|
AuditFields: utils.BuildAuditFields(nil),
|
||||||
}
|
}
|
||||||
if err := repositories.CustomerRepository.Create(db, customer); err != nil {
|
if err := repositories.CustomerRepository.Create(ctx.Tx, customer); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if err := repositories.CustomerIdentityRepository.Create(db, &models.CustomerIdentity{
|
if err := repositories.CustomerIdentityRepository.Create(ctx.Tx, &models.CustomerIdentity{
|
||||||
CustomerID: customer.ID,
|
CustomerID: customer.ID,
|
||||||
ExternalSource: externalSource,
|
ExternalSource: externalSource,
|
||||||
ExternalID: externalID,
|
ExternalID: externalID,
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ import (
|
|||||||
func TestEnsureExternalCustomerUpdatesNameFromExternalIdentity(t *testing.T) {
|
func TestEnsureExternalCustomerUpdatesNameFromExternalIdentity(t *testing.T) {
|
||||||
db := setupCustomerServiceTestDB(t)
|
db := setupCustomerServiceTestDB(t)
|
||||||
|
|
||||||
firstID, err := services.CustomerService.EnsureExternalCustomer(db, openidentity.ExternalUser{
|
var firstID int64
|
||||||
ExternalSource: enums.ExternalSourceUser,
|
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
||||||
ExternalID: "user-1",
|
id, err := services.CustomerService.EnsureExternalCustomer(ctx, openidentity.ExternalUser{
|
||||||
ExternalName: "张三",
|
ExternalSource: enums.ExternalSourceUser,
|
||||||
})
|
ExternalID: "user-1",
|
||||||
if err != nil {
|
ExternalName: "张三",
|
||||||
|
})
|
||||||
|
firstID = id
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
t.Fatalf("EnsureExternalCustomer() first error = %v", err)
|
t.Fatalf("EnsureExternalCustomer() first error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,12 +41,16 @@ func TestEnsureExternalCustomerUpdatesNameFromExternalIdentity(t *testing.T) {
|
|||||||
t.Fatalf("create conversation error = %v", err)
|
t.Fatalf("create conversation error = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secondID, err := services.CustomerService.EnsureExternalCustomer(db, openidentity.ExternalUser{
|
var secondID int64
|
||||||
ExternalSource: enums.ExternalSourceUser,
|
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
||||||
ExternalID: "user-1",
|
id, err := services.CustomerService.EnsureExternalCustomer(ctx, openidentity.ExternalUser{
|
||||||
ExternalName: "李四",
|
ExternalSource: enums.ExternalSourceUser,
|
||||||
})
|
ExternalID: "user-1",
|
||||||
if err != nil {
|
ExternalName: "李四",
|
||||||
|
})
|
||||||
|
secondID = id
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
t.Fatalf("EnsureExternalCustomer() second error = %v", err)
|
t.Fatalf("EnsureExternalCustomer() second error = %v", err)
|
||||||
}
|
}
|
||||||
if secondID != firstID {
|
if secondID != firstID {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func (s *customerSessionService) Exchange(channel *models.Channel, externalUser
|
|||||||
}
|
}
|
||||||
var customerID int64
|
var customerID int64
|
||||||
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
if err := sqls.WithTransaction(func(ctx *sqls.TxContext) error {
|
||||||
id, err := CustomerService.EnsureExternalCustomer(ctx.Tx, externalUser)
|
id, err := CustomerService.EnsureExternalCustomer(ctx, externalUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user