f
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// FadadaCorpAuthRecord 法大大企业授权相关数据(与 certifications 分离,便于签署链路复用)
|
||||
// open_corp_id:企业对本应用授权后,法大大分配的企业标识
|
||||
type FadadaCorpAuthRecord struct {
|
||||
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
|
||||
UserID string `json:"user_id" gorm:"type:varchar(36);not null;index;comment:用户ID"`
|
||||
CertificationID string `json:"certification_id" gorm:"type:varchar(36);index;comment:关联认证记录ID"`
|
||||
|
||||
AppID string `json:"app_id" gorm:"type:varchar(32);index;comment:法大大应用AppId"`
|
||||
CompanyName string `json:"company_name" gorm:"type:varchar(200);comment:企业名称"`
|
||||
UnifiedSocialCode string `json:"unified_social_code" gorm:"column:unified_social_code;type:varchar(50);index;comment:统一社会信用代码(corpIdentNo)"`
|
||||
ClientCorpID string `json:"client_corp_id" gorm:"column:client_corp_id;type:varchar(64);index;comment:应用内企业标识(clientCorpId)"`
|
||||
OpenCorpID string `json:"open_corp_id" gorm:"column:open_corp_id;type:varchar(64);index;comment:法大大企业openCorpId"`
|
||||
|
||||
BindingStatus string `json:"binding_status" gorm:"type:varchar(32);comment:授权绑定状态 unauthorized/authorized"`
|
||||
IdentStatus string `json:"ident_status" gorm:"type:varchar(32);comment:实名状态 unidentified/identified"`
|
||||
AvailableStatus string `json:"available_status" gorm:"type:varchar(32);comment:启用状态 disable/enable"`
|
||||
AuthScopes string `json:"auth_scopes" gorm:"type:text;comment:授权范围JSON数组字符串"`
|
||||
Source string `json:"source" gorm:"type:varchar(64);comment:数据来源"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at" gorm:"not null"`
|
||||
UpdatedAt time.Time `json:"updated_at" gorm:"not null"`
|
||||
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
|
||||
}
|
||||
|
||||
func (FadadaCorpAuthRecord) TableName() string {
|
||||
return "fadada_corp_auth_records"
|
||||
}
|
||||
|
||||
func NewFadadaCorpAuthRecord(userID, certificationID, appID, companyName, uscc, clientCorpID string) *FadadaCorpAuthRecord {
|
||||
now := time.Now()
|
||||
return &FadadaCorpAuthRecord{
|
||||
ID: uuid.New().String(),
|
||||
UserID: strings.TrimSpace(userID),
|
||||
CertificationID: strings.TrimSpace(certificationID),
|
||||
AppID: strings.TrimSpace(appID),
|
||||
CompanyName: strings.TrimSpace(companyName),
|
||||
UnifiedSocialCode: strings.TrimSpace(uscc),
|
||||
ClientCorpID: strings.TrimSpace(clientCorpID),
|
||||
Source: "init",
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *FadadaCorpAuthRecord) ApplyAuthStatus(
|
||||
openCorpID, clientCorpID, bindingStatus, identStatus, availableStatus string,
|
||||
authScopes []string,
|
||||
source string,
|
||||
) {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
if v := strings.TrimSpace(openCorpID); v != "" {
|
||||
r.OpenCorpID = v
|
||||
}
|
||||
if v := strings.TrimSpace(clientCorpID); v != "" {
|
||||
r.ClientCorpID = v
|
||||
}
|
||||
if v := strings.TrimSpace(bindingStatus); v != "" {
|
||||
r.BindingStatus = v
|
||||
}
|
||||
if v := strings.TrimSpace(identStatus); v != "" {
|
||||
r.IdentStatus = v
|
||||
}
|
||||
if v := strings.TrimSpace(availableStatus); v != "" {
|
||||
r.AvailableStatus = v
|
||||
}
|
||||
if len(authScopes) > 0 {
|
||||
r.AuthScopes = strings.Join(authScopes, ",")
|
||||
}
|
||||
if v := strings.TrimSpace(source); v != "" {
|
||||
r.Source = v
|
||||
}
|
||||
r.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
func (r *FadadaCorpAuthRecord) IsAuthorized() bool {
|
||||
return r != nil && strings.EqualFold(strings.TrimSpace(r.BindingStatus), "authorized") && strings.TrimSpace(r.OpenCorpID) != ""
|
||||
}
|
||||
@@ -34,6 +34,25 @@ type OrgIdentityQuery struct {
|
||||
ClientCorpID string
|
||||
}
|
||||
|
||||
// CorpAuthStatusQuery 企业授权状态查询(法大大 /corp/get;e签宝可返回未授权)
|
||||
type CorpAuthStatusQuery struct {
|
||||
CorpIdentNo string // 统一社会信用代码
|
||||
ClientCorpID string // 应用内企业标识
|
||||
OpenCorpID string // 法大大 openCorpId
|
||||
}
|
||||
|
||||
// CorpAuthStatusResult 企业授权状态
|
||||
type CorpAuthStatusResult struct {
|
||||
Supported bool // 当前平台是否支持主动查询授权状态
|
||||
Found bool // 本应用下是否已有企业记录
|
||||
Authorized bool // bindingStatus=authorized
|
||||
Identified bool // identStatus=identified
|
||||
OpenCorpID string
|
||||
ClientCorpID string
|
||||
BindingStatus string
|
||||
IdentStatus string
|
||||
}
|
||||
|
||||
// ContractGenerateRequest 合同模板填单
|
||||
type ContractGenerateRequest struct {
|
||||
AgreementNo string
|
||||
@@ -121,6 +140,8 @@ type CallbackEvent struct {
|
||||
SignRejected bool
|
||||
SignFlowID string
|
||||
AuthFlowID string
|
||||
OpenCorpID string
|
||||
ClientCorpID string
|
||||
OrgName string
|
||||
Raw map[string]interface{}
|
||||
}
|
||||
@@ -131,6 +152,8 @@ type SignPlatformProvider interface {
|
||||
|
||||
GenerateEnterpriseAuth(ctx context.Context, req *EnterpriseAuthRequest) (*AuthLinkResult, error)
|
||||
QueryOrgVerified(ctx context.Context, req *OrgIdentityQuery) (bool, error)
|
||||
// QueryCorpAuthStatus 查询企业是否已对本应用完成授权绑定(法大大:/corp/get bindingStatus)
|
||||
QueryCorpAuthStatus(ctx context.Context, req *CorpAuthStatusQuery) (*CorpAuthStatusResult, error)
|
||||
|
||||
GenerateContractFile(ctx context.Context, req *ContractGenerateRequest) (*ContractFileResult, error)
|
||||
CreateSignFlow(ctx context.Context, req *SignFlowCreateRequest) (*SignFlowResult, error)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"hyapi-server/internal/domains/certification/entities"
|
||||
)
|
||||
|
||||
// FadadaCorpAuthRecordRepository 法大大企业授权数据仓储
|
||||
type FadadaCorpAuthRecordRepository interface {
|
||||
Create(ctx context.Context, record *entities.FadadaCorpAuthRecord) error
|
||||
Update(ctx context.Context, record *entities.FadadaCorpAuthRecord) error
|
||||
FindByID(ctx context.Context, id string) (*entities.FadadaCorpAuthRecord, error)
|
||||
FindLatestByUserID(ctx context.Context, userID string) (*entities.FadadaCorpAuthRecord, error)
|
||||
FindByCertificationID(ctx context.Context, certificationID string) (*entities.FadadaCorpAuthRecord, error)
|
||||
FindByOpenCorpID(ctx context.Context, openCorpID string) (*entities.FadadaCorpAuthRecord, error)
|
||||
FindByUnifiedSocialCode(ctx context.Context, uscc string) (*entities.FadadaCorpAuthRecord, error)
|
||||
FindByClientCorpID(ctx context.Context, clientCorpID string) (*entities.FadadaCorpAuthRecord, error)
|
||||
// UpsertByBizKey 按认证ID优先,否则按 USCC/clientCorpId 合并写入
|
||||
UpsertByBizKey(ctx context.Context, record *entities.FadadaCorpAuthRecord) error
|
||||
}
|
||||
@@ -467,7 +467,9 @@ func (s *UserAggregateServiceImpl) CheckUnifiedSocialCodeExists(ctx context.Cont
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
// CreateOrUpdateEnterpriseInfo 认证域专用:写入/覆盖企业信息
|
||||
// CreateOrUpdateEnterpriseInfo 认证域专用:按两条链路写入企业信息
|
||||
// - 新用户:尚无企业信息 → 创建
|
||||
// - 重新认证:已有企业信息 → 覆盖更新
|
||||
func (s *UserAggregateServiceImpl) CreateOrUpdateEnterpriseInfo(
|
||||
ctx context.Context,
|
||||
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress string,
|
||||
@@ -476,19 +478,44 @@ func (s *UserAggregateServiceImpl) CreateOrUpdateEnterpriseInfo(
|
||||
if err != nil {
|
||||
return fmt.Errorf("用户不存在: %w", err)
|
||||
}
|
||||
if user.EnterpriseInfo == nil {
|
||||
enterpriseInfo, err := entities.NewEnterpriseInfo(userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
user.EnterpriseInfo = enterpriseInfo
|
||||
} else {
|
||||
err := user.EnterpriseInfo.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 统一校验 USCC(排除本人),新用户创建与重新认证更新均适用
|
||||
exists, err := s.CheckUnifiedSocialCodeExists(ctx, unifiedSocialCode, userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("检查统一社会信用代码失败: %w", err)
|
||||
}
|
||||
return s.SaveUser(ctx, user)
|
||||
if exists {
|
||||
return fmt.Errorf("统一社会信用代码已被其他用户使用")
|
||||
}
|
||||
|
||||
if user.HasEnterpriseInfo() {
|
||||
s.logger.Info("重新认证链路:更新已有企业信息",
|
||||
zap.String("user_id", userID),
|
||||
zap.String("unified_social_code", unifiedSocialCode),
|
||||
zap.String("enterprise_info_id", user.EnterpriseInfo.ID),
|
||||
)
|
||||
if err := user.UpdateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress); err != nil {
|
||||
return fmt.Errorf("更新企业信息失败: %w", err)
|
||||
}
|
||||
if err := s.SaveUser(ctx, user); err != nil {
|
||||
return fmt.Errorf("保存企业信息失败: %w", err)
|
||||
}
|
||||
s.logger.Info("重新认证链路:企业信息更新成功", zap.String("user_id", userID))
|
||||
return nil
|
||||
}
|
||||
|
||||
s.logger.Info("新用户认证链路:创建企业信息",
|
||||
zap.String("user_id", userID),
|
||||
zap.String("unified_social_code", unifiedSocialCode),
|
||||
)
|
||||
if err := user.CreateEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress); err != nil {
|
||||
return fmt.Errorf("创建企业信息失败: %w", err)
|
||||
}
|
||||
if err := s.SaveUser(ctx, user); err != nil {
|
||||
return fmt.Errorf("保存企业信息失败: %w", err)
|
||||
}
|
||||
s.logger.Info("新用户认证链路:企业信息创建成功", zap.String("user_id", userID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// CompleteCertification 完成认证
|
||||
|
||||
Reference in New Issue
Block a user