package wecom import ( "context" "time" "gorm.io/gorm" "gorm.io/gorm/clause" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" ) // ApplicationRepository 持久化企业微信应用配置。 type ApplicationRepository struct { db *gorm.DB } // NewApplicationRepository 创建企业微信应用 Repository。 func NewApplicationRepository(db *gorm.DB) *ApplicationRepository { return &ApplicationRepository{db: db} } // FindByIdentityForUpdate 在事务中锁定企业与应用唯一配置。 func (r *ApplicationRepository) FindByIdentityForUpdate(ctx context.Context, tx *gorm.DB, corpID string, agentID int64) (*model.WeComApplication, error) { var application model.WeComApplication err := tx.WithContext(ctx).Clauses(clause.Locking{Strength: "UPDATE"}). Where("corp_id = ? AND agent_id = ?", corpID, agentID).First(&application).Error if err == gorm.ErrRecordNotFound { return nil, nil } if err != nil { return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用配置失败") } return &application, nil } // Create 创建企业微信应用配置。 func (r *ApplicationRepository) Create(ctx context.Context, tx *gorm.DB, application *model.WeComApplication) error { if err := tx.WithContext(ctx).Create(application).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "创建企业微信应用配置失败") } return nil } // Update 更新企业微信应用配置及连接凭据。 func (r *ApplicationRepository) Update(ctx context.Context, tx *gorm.DB, application *model.WeComApplication) error { updates := map[string]any{ "name": application.Name, "secret": application.Secret, "callback_token": application.CallbackToken, "encoding_aes_key": application.EncodingAESKey, "default_creator_userid": application.DefaultCreatorUserID, "default_creator_name": application.DefaultCreatorName, "status": application.Status, "updated_by": application.UpdatedBy, "updated_at": application.UpdatedAt, } if err := tx.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ?", application.ID).Updates(updates).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信应用配置失败") } return nil } // UpdateDefaultCreator 更新应用默认审批发起人快照。 func (r *ApplicationRepository) UpdateDefaultCreator(ctx context.Context, tx *gorm.DB, applicationID uint, userID, name string, operatorID uint, updatedAt time.Time) error { if err := tx.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ? AND deleted_at IS NULL", applicationID).Updates(map[string]any{ "default_creator_userid": userID, "default_creator_name": name, "updated_by": operatorID, "updated_at": updatedAt, }).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信默认审批发起人失败") } return nil } // List 分页查询企业微信应用配置及连接凭据。 func (r *ApplicationRepository) List(ctx context.Context, page, pageSize int) ([]model.WeComApplication, int64, error) { query := r.db.WithContext(ctx).Model(&model.WeComApplication{}) var total int64 if err := query.Count(&total).Error; err != nil { return nil, 0, errors.Wrap(errors.CodeDatabaseError, err, "统计企业微信应用配置失败") } var applications []model.WeComApplication if err := query.Order("id ASC").Offset((page - 1) * pageSize).Limit(pageSize).Find(&applications).Error; err != nil { return nil, 0, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用列表失败") } return applications, total, nil } // GetEnabled 查询启用的企业微信应用及连接凭据。 func (r *ApplicationRepository) GetEnabled(ctx context.Context, applicationID uint) (*model.WeComApplication, error) { var application model.WeComApplication if err := r.db.WithContext(ctx).Where("id = ? AND status = ?", applicationID, constants.StatusEnabled).First(&application).Error; err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeWeComApplicationNotFound) } return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询企业微信应用配置失败") } return &application, nil } // MarkConnected 记录最近一次成功取得 access_token 的时间。 func (r *ApplicationRepository) MarkConnected(ctx context.Context, applicationID uint, connectedAt time.Time) error { if err := r.db.WithContext(ctx).Model(&model.WeComApplication{}).Where("id = ?", applicationID). Update("last_connected_at", connectedAt.UTC()).Error; err != nil { return errors.Wrap(errors.CodeDatabaseError, err, "更新企业微信最近连接时间失败") } return nil }