This commit is contained in:
2026-07-27 12:37:29 +08:00
parent dc9a98e893
commit 9429e4f6e0
20 changed files with 1066 additions and 61 deletions

View File

@@ -0,0 +1,210 @@
package certification
import (
"context"
"errors"
"strings"
"hyapi-server/internal/domains/certification/entities"
"hyapi-server/internal/domains/certification/repositories"
"hyapi-server/internal/shared/database"
"go.uber.org/zap"
"gorm.io/gorm"
)
const FadadaCorpAuthRecordsTable = "fadada_corp_auth_records"
type GormFadadaCorpAuthRecordRepository struct {
*database.CachedBaseRepositoryImpl
}
func NewGormFadadaCorpAuthRecordRepository(db *gorm.DB, logger *zap.Logger) *GormFadadaCorpAuthRecordRepository {
return &GormFadadaCorpAuthRecordRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, FadadaCorpAuthRecordsTable),
}
}
func (r *GormFadadaCorpAuthRecordRepository) Create(ctx context.Context, record *entities.FadadaCorpAuthRecord) error {
return r.CreateEntity(ctx, record)
}
func (r *GormFadadaCorpAuthRecordRepository) Update(ctx context.Context, record *entities.FadadaCorpAuthRecord) error {
return r.UpdateEntity(ctx, record)
}
func (r *GormFadadaCorpAuthRecordRepository) FindByID(ctx context.Context, id string) (*entities.FadadaCorpAuthRecord, error) {
var record entities.FadadaCorpAuthRecord
if err := r.GetDB(ctx).Where("id = ?", id).First(&record).Error; err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) FindLatestByUserID(ctx context.Context, userID string) (*entities.FadadaCorpAuthRecord, error) {
var record entities.FadadaCorpAuthRecord
err := r.GetDB(ctx).
Where("user_id = ?", userID).
Order("updated_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) FindByCertificationID(ctx context.Context, certificationID string) (*entities.FadadaCorpAuthRecord, error) {
if strings.TrimSpace(certificationID) == "" {
return nil, gorm.ErrRecordNotFound
}
var record entities.FadadaCorpAuthRecord
err := r.GetDB(ctx).
Where("certification_id = ?", certificationID).
Order("updated_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) FindByOpenCorpID(ctx context.Context, openCorpID string) (*entities.FadadaCorpAuthRecord, error) {
if strings.TrimSpace(openCorpID) == "" {
return nil, gorm.ErrRecordNotFound
}
var record entities.FadadaCorpAuthRecord
err := r.GetDB(ctx).
Where("open_corp_id = ?", openCorpID).
Order("updated_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) FindByUnifiedSocialCode(ctx context.Context, uscc string) (*entities.FadadaCorpAuthRecord, error) {
if strings.TrimSpace(uscc) == "" {
return nil, gorm.ErrRecordNotFound
}
var record entities.FadadaCorpAuthRecord
err := r.GetDB(ctx).
Where("unified_social_code = ?", uscc).
Order("updated_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) FindByClientCorpID(ctx context.Context, clientCorpID string) (*entities.FadadaCorpAuthRecord, error) {
if strings.TrimSpace(clientCorpID) == "" {
return nil, gorm.ErrRecordNotFound
}
var record entities.FadadaCorpAuthRecord
err := r.GetDB(ctx).
Where("client_corp_id = ?", clientCorpID).
Order("updated_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
func (r *GormFadadaCorpAuthRecordRepository) UpsertByBizKey(ctx context.Context, record *entities.FadadaCorpAuthRecord) error {
if record == nil {
return errors.New("法大大授权记录不能为空")
}
existing, err := r.findExisting(ctx, record)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if existing == nil {
return r.Create(ctx, record)
}
mergeFadadaCorpAuthRecord(existing, record)
return r.Update(ctx, existing)
}
func (r *GormFadadaCorpAuthRecordRepository) findExisting(ctx context.Context, record *entities.FadadaCorpAuthRecord) (*entities.FadadaCorpAuthRecord, error) {
if record.CertificationID != "" {
if rec, err := r.FindByCertificationID(ctx, record.CertificationID); err == nil {
return rec, nil
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if record.OpenCorpID != "" {
if rec, err := r.FindByOpenCorpID(ctx, record.OpenCorpID); err == nil {
return rec, nil
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if record.UnifiedSocialCode != "" {
if rec, err := r.FindByUnifiedSocialCode(ctx, record.UnifiedSocialCode); err == nil {
return rec, nil
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if record.ClientCorpID != "" {
if rec, err := r.FindByClientCorpID(ctx, record.ClientCorpID); err == nil {
return rec, nil
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
if record.UserID != "" {
if rec, err := r.FindLatestByUserID(ctx, record.UserID); err == nil {
return rec, nil
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
}
return nil, gorm.ErrRecordNotFound
}
func mergeFadadaCorpAuthRecord(dst, src *entities.FadadaCorpAuthRecord) {
if src.UserID != "" {
dst.UserID = src.UserID
}
if src.CertificationID != "" {
dst.CertificationID = src.CertificationID
}
if src.AppID != "" {
dst.AppID = src.AppID
}
if src.CompanyName != "" {
dst.CompanyName = src.CompanyName
}
if src.UnifiedSocialCode != "" {
dst.UnifiedSocialCode = src.UnifiedSocialCode
}
if src.ClientCorpID != "" {
dst.ClientCorpID = src.ClientCorpID
}
if src.OpenCorpID != "" {
dst.OpenCorpID = src.OpenCorpID
}
if src.BindingStatus != "" {
dst.BindingStatus = src.BindingStatus
}
if src.IdentStatus != "" {
dst.IdentStatus = src.IdentStatus
}
if src.AvailableStatus != "" {
dst.AvailableStatus = src.AvailableStatus
}
if src.AuthScopes != "" {
dst.AuthScopes = src.AuthScopes
}
if src.Source != "" {
dst.Source = src.Source
}
dst.UpdatedAt = src.UpdatedAt
}
var _ repositories.FadadaCorpAuthRecordRepository = (*GormFadadaCorpAuthRecordRepository)(nil)

View File

@@ -11,6 +11,7 @@ import (
"go.uber.org/zap"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"hyapi-server/internal/domains/user/entities"
"hyapi-server/internal/domains/user/repositories"
@@ -107,7 +108,48 @@ func (r *GormUserRepository) ExistsByUnifiedSocialCode(ctx context.Context, unif
}
func (r *GormUserRepository) Update(ctx context.Context, user entities.User) error {
return r.UpdateEntity(ctx, &user)
db := r.GetDB(ctx)
return db.Transaction(func(tx *gorm.DB) error {
// 避免 GORM 自动保存关联触发 ON CONFLICT受历史库索引差异影响
if err := tx.WithContext(ctx).Omit(clause.Associations).Save(&user).Error; err != nil {
return err
}
// 企业信息单独按 user_id 做更新或创建:新用户创建 / 重新认证更新
if user.EnterpriseInfo == nil {
return nil
}
enterpriseInfo := *user.EnterpriseInfo
enterpriseInfo.UserID = user.ID
enterpriseInfo.User = nil
var count int64
if err := tx.WithContext(ctx).
Model(&entities.EnterpriseInfo{}).
Where("user_id = ?", user.ID).
Count(&count).Error; err != nil {
return err
}
if count > 0 {
updates := map[string]interface{}{
"company_name": enterpriseInfo.CompanyName,
"unified_social_code": enterpriseInfo.UnifiedSocialCode,
"legal_person_name": enterpriseInfo.LegalPersonName,
"legal_person_id": enterpriseInfo.LegalPersonID,
"legal_person_phone": enterpriseInfo.LegalPersonPhone,
"enterprise_address": enterpriseInfo.EnterpriseAddress,
}
return tx.WithContext(ctx).
Model(&entities.EnterpriseInfo{}).
Where("user_id = ?", user.ID).
Updates(updates).Error
}
return tx.WithContext(ctx).Create(&enterpriseInfo).Error
})
}
func (r *GormUserRepository) CreateBatch(ctx context.Context, users []entities.User) error {

View File

@@ -56,6 +56,13 @@ func (p *Provider) QueryOrgVerified(ctx context.Context, req *ports.OrgIdentityQ
return identity != nil && identity.Data.RealnameStatus == 1, nil
}
func (p *Provider) QueryCorpAuthStatus(ctx context.Context, req *ports.CorpAuthStatusQuery) (*ports.CorpAuthStatusResult, error) {
_ = ctx
_ = req
// e签宝无对等「查询企业授权状态」接口走取链/已实名兜底逻辑
return &ports.CorpAuthStatusResult{Supported: false}, nil
}
func (p *Provider) GenerateContractFile(ctx context.Context, req *ports.ContractGenerateRequest) (*ports.ContractFileResult, error) {
_ = ctx
components := map[string]string{

View File

@@ -54,6 +54,34 @@ func (p *Provider) QueryOrgVerified(ctx context.Context, req *ports.OrgIdentityQ
})
}
func (p *Provider) QueryCorpAuthStatus(ctx context.Context, req *ports.CorpAuthStatusQuery) (*ports.CorpAuthStatusResult, error) {
_ = ctx
if req == nil {
return &ports.CorpAuthStatusResult{Supported: true, Found: false}, nil
}
res, err := p.client.QueryCorpAuth(&sharedfadada.QueryCorpAuthRequest{
CorpIdentNo: req.CorpIdentNo,
ClientCorpID: req.ClientCorpID,
OpenCorpID: req.OpenCorpID,
})
if err != nil {
return nil, err
}
if res == nil {
return &ports.CorpAuthStatusResult{Supported: true, Found: false}, nil
}
return &ports.CorpAuthStatusResult{
Supported: true,
Found: res.Found,
Authorized: res.Authorized,
Identified: res.Identified,
OpenCorpID: res.OpenCorpID,
ClientCorpID: res.ClientCorpID,
BindingStatus: res.BindingStatus,
IdentStatus: res.IdentStatus,
}, nil
}
// GenerateContractFile 法大大走签署任务模板(/sign-task/create-with-template
// 此处返回空结果,实际填单由 CreateSignFlow 通过 /sign-task/field/fill-values 完成。
func (p *Provider) GenerateContractFile(ctx context.Context, req *ports.ContractGenerateRequest) (*ports.ContractFileResult, error) {
@@ -199,10 +227,12 @@ func (p *Provider) ParseCallback(ctx context.Context, headers map[string]string,
return nil, err
}
out := &ports.CallbackEvent{
Event: ev.Event,
SignFlowID: ev.SignTaskID,
AuthFlowID: firstNonEmpty(ev.ClientCorpID, ev.OpenCorpID),
Raw: ev.Raw,
Event: ev.Event,
SignFlowID: ev.SignTaskID,
AuthFlowID: firstNonEmpty(ev.ClientCorpID, ev.OpenCorpID),
OpenCorpID: ev.OpenCorpID,
ClientCorpID: ev.ClientCorpID,
Raw: ev.Raw,
}
if ev.IsSignCompletedCallback() {
out.SignCompleted = true