固化七月迭代审计治理进展以隔离线上热修

Constraint: 切换 main 前必须保存当前七月分支全部项目进展,套餐生效提案仅属于 Iteration/7-11。

Rejected: 将七月套餐修复直接移植到 main | 两个分支的可靠投递架构不同。

Confidence: medium

Scope-risk: broad

Directive: 不得将本提交整体 cherry-pick 到 main;main 套餐热修必须基于其纯 Asynq 代码独立实施。

Tested: git diff --check;openspec validate fix-package-activation-starvation --strict。

Not-tested: 按用户要求未运行自动化测试;go build ./... 因当前审计改造中的 Enterprise 模型字面量和 role.recordFailure 参数类型错误未通过。
This commit is contained in:
2026-08-03 09:47:22 +08:00
parent cf2ff0ac1c
commit b3499adfca
114 changed files with 16961 additions and 2782 deletions

View File

@@ -0,0 +1,84 @@
// Package auditcontext 提供跨 HTTP、异步任务和外部回调传播的审计上下文。
package auditcontext
import "context"
type contextKey struct{}
// Context 保存入口提供的真实操作者与链路信息,不包含业务动作或资源事实。
type Context struct {
ActorKind string
ActorID string
ActorName string
ActorShopID *uint
ActorEnterpriseID *uint
Source string
RequestID string
CorrelationID string
ParentEventID string
RequestPath string
RequestMethod string
IPAddress string
UserAgent string
}
// With 合并审计上下文;非空新值覆盖旧值,便于认证中间件覆盖 HTTP 基础信息。
func With(ctx context.Context, value Context) context.Context {
if ctx == nil {
ctx = context.Background()
}
merged := From(ctx)
merge(&merged, value)
return context.WithValue(ctx, contextKey{}, merged)
}
// From 读取审计上下文;未设置时返回零值。
func From(ctx context.Context) Context {
if ctx == nil {
return Context{}
}
value, _ := ctx.Value(contextKey{}).(Context)
return value
}
func merge(target *Context, value Context) {
if value.ActorKind != "" {
target.ActorKind = value.ActorKind
}
if value.ActorID != "" {
target.ActorID = value.ActorID
}
if value.ActorName != "" {
target.ActorName = value.ActorName
}
if value.ActorShopID != nil {
target.ActorShopID = value.ActorShopID
}
if value.ActorEnterpriseID != nil {
target.ActorEnterpriseID = value.ActorEnterpriseID
}
if value.Source != "" {
target.Source = value.Source
}
if value.RequestID != "" {
target.RequestID = value.RequestID
}
if value.CorrelationID != "" {
target.CorrelationID = value.CorrelationID
}
if value.ParentEventID != "" {
target.ParentEventID = value.ParentEventID
}
if value.RequestPath != "" {
target.RequestPath = value.RequestPath
}
if value.RequestMethod != "" {
target.RequestMethod = value.RequestMethod
}
if value.IPAddress != "" {
target.IPAddress = value.IPAddress
}
if value.UserAgent != "" {
target.UserAgent = value.UserAgent
}
}

View File

@@ -0,0 +1,33 @@
// Package auditfailure 提供失败审计二次写入故障的最小进程内观测。
package auditfailure
import (
"sync/atomic"
"go.uber.org/zap"
"github.com/break/junhong_cmp_fiber/pkg/logger"
)
var secondaryWriteFailures atomic.Uint64
// RecordSecondaryWriteFailure 累计失败审计二次写入故障并记录 critical 安全日志。
func RecordSecondaryWriteFailure(action, resourceKey, requestID, correlationID, originalErrorCode string, err error) {
count := secondaryWriteFailures.Add(1)
logger.GetAppLogger().Error(
"失败或拒绝审计二次写入失败",
zap.String("severity", "critical"),
zap.String("action", action),
zap.String("resource_key", resourceKey),
zap.String("request_id", requestID),
zap.String("correlation_id", correlationID),
zap.String("original_error_code", originalErrorCode),
zap.Uint64("secondary_write_failure_count", count),
zap.Error(err),
)
}
// SecondaryWriteFailureCount 返回当前进程累计的失败审计二次写入故障数。
func SecondaryWriteFailureCount() uint64 {
return secondaryWriteFailures.Load()
}

303
pkg/constants/audit.go Normal file
View File

@@ -0,0 +1,303 @@
package constants
const (
// AuditActionAccountCreated 表示创建账号。
AuditActionAccountCreated = "account.created"
// AuditActionAccountUpdated 表示更新账号基础资料或状态。
AuditActionAccountUpdated = "account.updated"
// AuditActionAccountDeleted 表示软删除账号。
AuditActionAccountDeleted = "account.deleted"
// AuditActionAccountPasswordReset 表示管理员重置账号密码。
AuditActionAccountPasswordReset = "account.update_password"
// AuditActionAccountPasswordChanged 表示账号本人修改密码。
AuditActionAccountPasswordChanged = "auth.change_password"
// AuditActionAccountWeComBound 表示绑定账号企业微信身份。
AuditActionAccountWeComBound = "account.bind_we_com"
// AuditActionAuthLogin 表示后台账号登录。
AuditActionAuthLogin = "auth.login"
// AuditActionAuthLogout 表示后台账号退出登录。
AuditActionAuthLogout = "auth.logout"
// AuditActionAuthTokenRefreshed 表示后台账号刷新访问令牌。
AuditActionAuthTokenRefreshed = "auth.refresh_token"
// AuditActionAccountRolesAssigned 表示为账号分配角色。
AuditActionAccountRolesAssigned = "account.assign_roles"
// AuditActionAccountRoleRemoved 表示移除账号角色。
AuditActionAccountRoleRemoved = "account.remove_role"
// AuditActionShopRolesAssigned 表示为店铺分配角色。
AuditActionShopRolesAssigned = "shop.assign_shop_roles"
// AuditActionShopRoleDeleted 表示移除店铺角色。
AuditActionShopRoleDeleted = "shop.delete_shop_role"
// AuditActionShopCreated 表示创建店铺。
AuditActionShopCreated = "shop.create"
// AuditActionShopUpdated 表示更新店铺基础资料。
AuditActionShopUpdated = "shop.update"
// AuditActionShopEnabled 表示启用店铺。
AuditActionShopEnabled = "shop.enable"
// AuditActionShopDisabled 表示禁用店铺。
AuditActionShopDisabled = "shop.disable"
// AuditActionShopDeleted 表示删除店铺。
AuditActionShopDeleted = "shop.delete"
// AuditActionShopBusinessOwnerUpdated 表示更新店铺业务员归属。
AuditActionShopBusinessOwnerUpdated = "shop.update_business_owner"
// AuditActionShopClientLoginLimitUpdated 表示更新店铺 C 端登录限制。
AuditActionShopClientLoginLimitUpdated = "shop.update_client_login_limit"
// AuditActionEnterpriseCreated 表示创建企业及初始企业账号。
AuditActionEnterpriseCreated = "enterprise.create"
// AuditActionEnterpriseUpdated 表示更新企业基础资料。
AuditActionEnterpriseUpdated = "enterprise.update"
// AuditActionEnterpriseStatusUpdated 表示更新企业及企业账号状态。
AuditActionEnterpriseStatusUpdated = "enterprise.update_status"
// AuditActionEnterprisePasswordUpdated 表示更新企业账号密码。
AuditActionEnterprisePasswordUpdated = "enterprise.update_password"
// AuditActionEnterpriseCardsAllocated 表示向企业授权独立卡。
AuditActionEnterpriseCardsAllocated = "enterprise_card.allocate_cards"
// AuditActionEnterpriseCardsRecalled 表示回收企业独立卡授权。
AuditActionEnterpriseCardsRecalled = "enterprise_card.recall_cards"
// AuditActionEnterpriseCardRemarkUpdated 表示更新企业卡授权备注。
AuditActionEnterpriseCardRemarkUpdated = "enterprise_card.update_record_remark"
// AuditActionEnterpriseDevicesAllocated 表示向企业授权设备及其绑定卡。
AuditActionEnterpriseDevicesAllocated = "enterprise_device.allocate_devices"
// AuditActionEnterpriseDevicesRecalled 表示回收企业设备及其绑定卡授权。
AuditActionEnterpriseDevicesRecalled = "enterprise_device.recall_devices"
// AuditActionPersonalCustomerProfileUpdated 表示个人客户更新资料。
AuditActionPersonalCustomerProfileUpdated = "personal_customer.update_profile"
// AuditActionPersonalCustomerPhoneBound 表示个人客户绑定手机号。
AuditActionPersonalCustomerPhoneBound = "personal_customer.bind_phone"
// AuditActionPersonalCustomerPhoneChanged 表示个人客户更换手机号。
AuditActionPersonalCustomerPhoneChanged = "personal_customer.change_phone"
// AuditActionPersonalCustomerWechatIdentityUpdated 表示创建或同步个人客户微信主体。
AuditActionPersonalCustomerWechatIdentityUpdated = "personal_customer.update_wechat_identity"
// AuditActionSystemConfigUpdated 表示更新受控系统配置。
AuditActionSystemConfigUpdated = "system_config.updated"
// AuditActionOutboxReplayed 表示人工重放 Outbox 事件。
AuditActionOutboxReplayed = "outbox.replayed"
// AuditActionOutboxExpiredLeaseReleased 表示人工释放 Outbox 过期租约。
AuditActionOutboxExpiredLeaseReleased = "outbox.expired_lease_released"
// AuditActionDeviceBatchAllocationCompleted 表示设备批量分配根事件。
AuditActionDeviceBatchAllocationCompleted = "device.batch_allocation.completed"
// AuditActionDeviceBatchAllocationItem 表示设备批量分配资源子事件。
AuditActionDeviceBatchAllocationItem = "device.batch_allocation.item"
// AuditActionWeComCredentialsRead 表示读取企业微信应用明文凭据。
AuditActionWeComCredentialsRead = "wecom.application.credentials_read"
// AuditActionRoleCreated 表示创建角色。
AuditActionRoleCreated = "role.create"
// AuditActionRoleUpdated 表示更新角色。
AuditActionRoleUpdated = "role.update"
// AuditActionRoleStatusUpdated 表示更新角色状态。
AuditActionRoleStatusUpdated = "role.update_status"
// AuditActionRoleDefaultCreditUpdated 表示更新角色默认信用额度。
AuditActionRoleDefaultCreditUpdated = "role.update_default_credit"
// AuditActionRoleDeleted 表示删除角色。
AuditActionRoleDeleted = "role.delete"
// AuditActionRolePermissionsAssigned 表示配置角色权限。
AuditActionRolePermissionsAssigned = "role.assign_permissions"
// AuditActionRolePermissionRemoved 表示移除单个角色权限。
AuditActionRolePermissionRemoved = "role.remove_permission"
// AuditActionRolePermissionsBatchRemoved 表示批量移除角色权限。
AuditActionRolePermissionsBatchRemoved = "role.batch_remove_permissions"
// AuditActionPermissionCreated 表示创建权限。
AuditActionPermissionCreated = "permission.create"
// AuditActionPermissionUpdated 表示更新权限。
AuditActionPermissionUpdated = "permission.update"
// AuditActionPermissionDeleted 表示删除权限。
AuditActionPermissionDeleted = "permission.delete"
// AuditOperationSystemConfigUpdate 表示系统配置旧接缝传入的操作类型。
AuditOperationSystemConfigUpdate = "system_config_update"
// AuditOperationOutboxReplay 表示 Outbox 人工重放接缝操作类型。
AuditOperationOutboxReplay = "outbox_replay"
// AuditOperationOutboxReleaseExpiredLease 表示 Outbox 人工释放过期租约接缝操作类型。
AuditOperationOutboxReleaseExpiredLease = "outbox_release_expired_lease"
)
const (
// AuditResourceSystemConfig 表示受控系统配置资源。
AuditResourceSystemConfig = "system_config"
// AuditResourceOutboxEvent 表示公共 Outbox 事件资源。
AuditResourceOutboxEvent = "outbox_event"
// AuditResourceDeviceBatchTask 表示设备批量分配任务资源。
AuditResourceDeviceBatchTask = "device_batch_task"
// AuditResourceDevice 表示设备资源。
AuditResourceDevice = "device"
// AuditResourceIotCard 表示 IoT 卡资源。
AuditResourceIotCard = "iot_card"
// AuditResourceShop 表示店铺资源。
AuditResourceShop = "shop"
// AuditResourceOrder 表示订单资源。
AuditResourceOrder = "order"
// AuditResourceRefund 表示退款资源。
AuditResourceRefund = "refund"
// AuditResourceAccount 表示后台账号资源。
AuditResourceAccount = "account"
// AuditResourceRole 表示后台角色资源。
AuditResourceRole = "role"
// AuditResourcePermission 表示后台权限资源。
AuditResourcePermission = "permission"
// AuditResourceEnterprise 表示企业资源。
AuditResourceEnterprise = "enterprise"
// AuditResourceDeviceSIMBinding 表示设备卡槽绑定资源。
AuditResourceDeviceSIMBinding = "device_sim_binding"
// AuditResourceAssetAllocationRecord 表示资产分配记录资源。
AuditResourceAssetAllocationRecord = "asset_allocation_record"
// AuditResourceExchangeOrder 表示换货单资源。
AuditResourceExchangeOrder = "exchange_order"
// AuditResourceAgentRecharge 表示代理充值单资源。
AuditResourceAgentRecharge = "agent_recharge"
// AuditResourceAssetWallet 表示资产钱包资源。
AuditResourceAssetWallet = "asset_wallet"
// AuditResourceApprovalInstance 表示审批实例资源。
AuditResourceApprovalInstance = "approval_instance"
// AuditResourceWeComApplication 表示企业微信应用配置资源。
AuditResourceWeComApplication = "wecom_application"
// AuditResourceAuthentication 表示不含 Token 或 Cookie 的认证状态资源。
AuditResourceAuthentication = "authentication"
// AuditResourceEnterpriseCardAuthorization 表示企业卡授权记录资源。
AuditResourceEnterpriseCardAuthorization = "enterprise_card_authorization"
// AuditResourceEnterpriseDeviceAuthorization 表示企业设备授权记录资源。
AuditResourceEnterpriseDeviceAuthorization = "enterprise_device_authorization"
// AuditResourcePersonalCustomer 表示个人客户资源。
AuditResourcePersonalCustomer = "personal_customer"
// AuditResourcePersonalCustomerPhone 表示个人客户手机号资源。
AuditResourcePersonalCustomerPhone = "personal_customer_phone"
// AuditResourcePersonalCustomerOpenID 表示个人客户微信 OpenID 资源。
AuditResourcePersonalCustomerOpenID = "personal_customer_openid"
// AuditResourceRelationPrimary 表示事件的主要资源。
AuditResourceRelationPrimary = "primary"
// AuditResourceRelationAffected 表示被本次动作改变的资源。
AuditResourceRelationAffected = "affected"
// AuditResourceRelationReference 表示本次动作引用但未改变的资源。
AuditResourceRelationReference = "reference"
// AuditResourceRoleConfig 表示配置资源角色。
AuditResourceRoleConfig = "config"
// AuditResourceRoleRecoveryTarget 表示人工恢复裁决的目标事件。
AuditResourceRoleRecoveryTarget = "recovery_target"
// AuditResourceRoleBatchTask 表示批量根事件的任务资源。
AuditResourceRoleBatchTask = "batch_task"
// AuditResourceRoleBatchItem 表示批量子事件的单项资源。
AuditResourceRoleBatchItem = "batch_item"
// AuditResourceRoleSensitiveReadTarget 表示敏感读取目标资源。
AuditResourceRoleSensitiveReadTarget = "sensitive_read_target"
// AuditResourceRoleAccountTarget 表示账号生命周期的目标账号。
AuditResourceRoleAccountTarget = "account_target"
// AuditResourceRoleAccountScope 表示账号归属的店铺或企业。
AuditResourceRoleAccountScope = "account_scope"
// AuditResourceRoleAccountRole 表示账号实际持有的角色。
AuditResourceRoleAccountRole = "account_role"
// AuditResourceRoleAuthentication 表示账号关联的认证状态。
AuditResourceRoleAuthentication = "authentication"
// AuditResourceRoleAccessRole 表示角色权限配置中的角色目标。
AuditResourceRoleAccessRole = "role_target"
// AuditResourceRoleAccessPermission 表示角色权限配置中的权限目标。
AuditResourceRoleAccessPermission = "permission_target"
// AuditResourceRoleShopRole 表示店铺实际持有的角色。
AuditResourceRoleShopRole = "shop_role"
// AuditResourceRoleShopTarget 表示店铺操作的主要目标。
AuditResourceRoleShopTarget = "shop_target"
// AuditResourceRoleShopParent 表示店铺的上级店铺。
AuditResourceRoleShopParent = "shop_parent"
// AuditResourceRoleShopAccount 表示店铺直接影响的账号。
AuditResourceRoleShopAccount = "shop_account"
// AuditResourceRoleShopBusinessOwner 表示店铺当前业务员账号。
AuditResourceRoleShopBusinessOwner = "shop_business_owner"
// AuditResourceRoleShopPreviousBusinessOwner 表示店铺原业务员账号。
AuditResourceRoleShopPreviousBusinessOwner = "shop_previous_business_owner"
// AuditResourceRoleEnterpriseTarget 表示企业操作的主要目标。
AuditResourceRoleEnterpriseTarget = "enterprise_target"
// AuditResourceRoleEnterpriseOwnerShop 表示企业归属店铺。
AuditResourceRoleEnterpriseOwnerShop = "enterprise_owner_shop"
// AuditResourceRoleEnterpriseAccount 表示企业关联账号。
AuditResourceRoleEnterpriseAccount = "enterprise_account"
// AuditResourceRoleEnterpriseAuthorizedCard 表示企业授权涉及的卡。
AuditResourceRoleEnterpriseAuthorizedCard = "enterprise_authorized_card"
// AuditResourceRoleEnterpriseCardAuthorization 表示企业卡授权记录。
AuditResourceRoleEnterpriseCardAuthorization = "enterprise_card_authorization"
// AuditResourceRoleEnterpriseAuthorizedDevice 表示企业授权涉及的设备。
AuditResourceRoleEnterpriseAuthorizedDevice = "enterprise_authorized_device"
// AuditResourceRoleEnterpriseDeviceBinding 表示企业设备授权涉及的卡槽绑定。
AuditResourceRoleEnterpriseDeviceBinding = "enterprise_device_binding"
// AuditResourceRoleEnterpriseDeviceAuthorization 表示企业设备授权记录。
AuditResourceRoleEnterpriseDeviceAuthorization = "enterprise_device_authorization"
// AuditResourceRolePersonalCustomerTarget 表示个人客户操作的主体目标。
AuditResourceRolePersonalCustomerTarget = "personal_customer_target"
// AuditResourceRolePersonalCustomerPhone 表示个人客户手机号关系。
AuditResourceRolePersonalCustomerPhone = "personal_customer_phone"
// AuditResourceRolePersonalCustomerWechatIdentity 表示个人客户微信主体关系。
AuditResourceRolePersonalCustomerWechatIdentity = "personal_customer_wechat_identity"
)
const (
// AuditActorAccount 表示已认证人工账号。
AuditActorAccount = "account"
// AuditActorPersonalCustomer 表示已认证个人客户。
AuditActorPersonalCustomer = "personal_customer"
// AuditActorOpenAPI 表示通过代理 OpenAPI 调用的账号。
AuditActorOpenAPI = "openapi"
// AuditActorSystemTask 表示异步 Worker 执行的系统任务。
AuditActorSystemTask = "system_task"
// AuditActorScheduledJob 表示由 Scheduler 触发的计划任务。
AuditActorScheduledJob = "scheduled_job"
// AuditActorExternalSystem 表示经验证的外部系统回调。
AuditActorExternalSystem = "external_system"
// AuditSourceAdminAPI 表示后台管理 API 入口。
AuditSourceAdminAPI = "admin_api"
// AuditSourcePersonalAPI 表示个人客户 API 入口。
AuditSourcePersonalAPI = "personal_api"
// AuditSourceOpenAPI 表示代理 OpenAPI 入口。
AuditSourceOpenAPI = "openapi"
// AuditSourceWorker 表示异步 Worker 入口。
AuditSourceWorker = "worker"
// AuditSourceScheduler 表示计划任务入口。
AuditSourceScheduler = "scheduler"
// AuditSourceCallback 表示外部系统回调入口。
AuditSourceCallback = "callback"
// AuditScopePlatform 表示平台级业务范围。
AuditScopePlatform = "platform"
// AuditScopePersonalCustomer 表示个人客户本人业务范围。
AuditScopePersonalCustomer = "personal_customer"
)
const (
// AuditResultSuccess 表示业务操作成功。
AuditResultSuccess = "success"
// AuditResultFailed 表示业务操作执行失败。
AuditResultFailed = "failed"
// AuditResultDenied 表示业务规则或权限拒绝。
AuditResultDenied = "denied"
// AuditResultPartial 表示批量操作部分成功。
AuditResultPartial = "partial"
// AuditResultUnknown 表示业务结果暂时无法确认。
AuditResultUnknown = "unknown"
)
const (
// AuditRiskLow 表示低风险审计动作。
AuditRiskLow = "low"
// AuditRiskHigh 表示高风险审计动作。
AuditRiskHigh = "high"
// AuditRiskNormal 表示常规风险审计动作。
AuditRiskNormal = "normal"
// AuditRiskCritical 表示严重风险审计动作。
AuditRiskCritical = "critical"
// AuditCategoryConfiguration 表示关键配置类别。
AuditCategoryConfiguration = "configuration"
// AuditCategoryReliability 表示可靠事件运维类别。
AuditCategoryReliability = "reliability"
// AuditCategoryAsset 表示资产变更类别。
AuditCategoryAsset = "asset"
// AuditCategorySecurity 表示安全与敏感读取类别。
AuditCategorySecurity = "security"
// AuditCategoryIdentity 表示账号与权限身份类别。
AuditCategoryIdentity = "identity"
// AuditCategoryBusiness 表示通用业务配置类别。
AuditCategoryBusiness = "business"
// AuditSubjectInternalOnly 表示仅平台内部可见。
AuditSubjectInternalOnly = "internal_only"
// AuditSubjectResult 表示主体仅可查看安全业务结论。
AuditSubjectResult = "subject_result"
// AuditSubjectDetail 表示主体可查看注册表允许的结构化业务详情。
AuditSubjectDetail = "subject_detail"
)
const (
// AuditJSONMaxBytes 是单个审计 JSON 字段允许的最大字节数。
AuditJSONMaxBytes = 16 * 1024
)

View File

@@ -2,6 +2,28 @@ package constants
import "time"
const (
// IntegrationIDMaxLength 是外部交互稳定ID的数据库长度上限。
IntegrationIDMaxLength = 64
// IntegrationTriggerSeriesMaxLength 是技术尝试序列ID的数据库长度上限。
IntegrationTriggerSeriesMaxLength = 64
// IntegrationCorrelationIDMaxLength 是跨业务链路关联ID的数据库长度上限。
IntegrationCorrelationIDMaxLength = 100
// IntegrationResourceIDMaxLength 是外部交互本地资源ID的数据库长度上限。
IntegrationResourceIDMaxLength = 128
// IntegrationResourceKeyMaxLength 是外部交互资源稳定Key的数据库长度上限。
IntegrationResourceKeyMaxLength = 128
// IntegrationProviderMessageMaxLength 是外部交互结果摘要的数据库长度上限。
IntegrationProviderMessageMaxLength = 500
// IntegrationSafeMessagePrefix 标识调用方已提供的受控可读业务结果摘要。
IntegrationSafeMessagePrefix = "业务结果摘要:"
// IntegrationQueryMaxRange 是调查列表允许的最大连续时间范围。
IntegrationQueryMaxRange = 31 * 24 * time.Hour
// IntegrationPendingStaleAfter 是待处理尝试进入陈旧统计的时长。
IntegrationPendingStaleAfter = 5 * time.Minute
)
const (
// IntegrationDirectionInbound 表示外部系统调用本系统。
IntegrationDirectionInbound = "inbound"
@@ -85,3 +107,86 @@ func IntegrationResultName(result string) string {
}
return names[result]
}
const (
// IntegrationResultCategoryProcessing 表示仍在处理。
IntegrationResultCategoryProcessing = "processing"
// IntegrationResultCategorySucceeded 表示外部请求实际成功。
IntegrationResultCategorySucceeded = "succeeded"
// IntegrationResultCategoryIndeterminate 表示结果无法确认。
IntegrationResultCategoryIndeterminate = "indeterminate"
// IntegrationResultCategoryFailed 表示外部请求或载荷明确失败。
IntegrationResultCategoryFailed = "failed"
// IntegrationResultCategoryNotSent 表示外部请求未发送。
IntegrationResultCategoryNotSent = "not_sent"
)
// IntegrationResultCategory 返回外部尝试的稳定派生类别。
func IntegrationResultCategory(result string) string {
switch result {
case IntegrationResultPending:
return IntegrationResultCategoryProcessing
case IntegrationResultSuccess:
return IntegrationResultCategorySucceeded
case IntegrationResultUnknown:
return IntegrationResultCategoryIndeterminate
case IntegrationResultFailed, IntegrationResultNotFound, IntegrationResultInvalidPayload, IntegrationResultConflict:
return IntegrationResultCategoryFailed
case IntegrationResultIgnored, IntegrationResultMerged, IntegrationResultRateLimited, IntegrationResultCompleted, IntegrationResultCancelled:
return IntegrationResultCategoryNotSent
default:
return ""
}
}
// IntegrationProviderName 返回外部提供方中文名称。
func IntegrationProviderName(provider string) string {
names := map[string]string{
IntegrationProviderCTCC: "中国电信", IntegrationProviderCMCC: "中国移动",
IntegrationProviderCUCC: "中国联通", IntegrationProviderWechatPay: "微信支付",
IntegrationProviderAlipay: "支付宝", IntegrationProviderWeCom: "企业微信",
IntegrationProviderGateway: "Gateway",
}
if name := names[provider]; name != "" {
return name
}
return "未知提供方"
}
// IntegrationDirectionName 返回外部交互方向中文名称。
func IntegrationDirectionName(direction string) string {
switch direction {
case IntegrationDirectionInbound:
return "入站"
case IntegrationDirectionOutbound:
return "出站"
default:
return "未知方向"
}
}
// IntegrationOperationName 返回已注册外部操作中文名称。
func IntegrationOperationName(operation string) string {
names := map[string]string{
IntegrationOperationCTCCRealnameCallback: "接收实名结果回调",
IntegrationOperationCUCCRealnameRemovalCallback: "接收解除实名回调",
IntegrationOperationPaymentPreCreate: "支付预下单", IntegrationOperationPaymentQuery: "支付查单",
IntegrationOperationPaymentCallback: "接收支付回调",
IntegrationOperationWeComAccessToken: "获取企业微信访问令牌",
IntegrationOperationWeComVisibleMembers: "查询企业微信可见成员",
IntegrationOperationWeComVisibleDepartments: "查询企业微信可见部门",
IntegrationOperationWeComTemplateDetail: "查询企业微信审批模板",
IntegrationOperationWeComAttachmentUpload: "上传企业微信审批附件",
IntegrationOperationWeComApprovalSubmit: "提交企业微信审批",
IntegrationOperationWeComApprovalCallback: "接收企业微信审批回调",
IntegrationOperationWeComApprovalDetail: "查询企业微信审批详情",
IntegrationOperationWeComApprovalInfo: "查询企业微信审批单号",
IntegrationOperationGatewayRealname: "查询实名状态", IntegrationOperationGatewayTraffic: "查询流量",
IntegrationOperationGatewayNetwork: "查询卡网络状态", IntegrationOperationGatewayDeviceInfo: "查询设备信息",
IntegrationOperationGatewaySpeedTier: "设置卡限速档位",
}
if name := names[operation]; name != "" {
return name
}
return "未知外部操作"
}

View File

@@ -7,6 +7,7 @@ import (
"net/url"
"time"
"github.com/break/junhong_cmp_fiber/pkg/auditcontext"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/sanitizer"
"github.com/bytedance/sonic"
@@ -154,8 +155,10 @@ func MiddlewareWithLogger(accessLogger *zap.Logger) fiber.Handler {
// 注入请求上下文,供 Service 层审计日志复用
ctx := c.UserContext()
requestID := ""
if rid := c.Locals(constants.ContextKeyRequestID); rid != nil {
if requestID, ok := rid.(string); ok && requestID != "" {
if value, ok := rid.(string); ok && value != "" {
requestID = value
ctx = context.WithValue(ctx, constants.ContextKeyRequestID, requestID)
}
}
@@ -163,6 +166,11 @@ func MiddlewareWithLogger(accessLogger *zap.Logger) fiber.Handler {
ctx = context.WithValue(ctx, constants.ContextKeyUserAgent, c.Get("User-Agent"))
ctx = context.WithValue(ctx, constants.ContextKeyRequestPath, c.Path())
ctx = context.WithValue(ctx, constants.ContextKeyRequestMethod, c.Method())
ctx = auditcontext.With(ctx, auditcontext.Context{
RequestID: requestID, CorrelationID: requestID,
RequestPath: c.Path(), RequestMethod: c.Method(),
IPAddress: c.IP(), UserAgent: c.Get("User-Agent"),
})
c.SetUserContext(ctx)
// 获取请求 body在 c.Next() 之前读取)
@@ -182,7 +190,7 @@ func MiddlewareWithLogger(accessLogger *zap.Logger) fiber.Handler {
duration := time.Since(startTime)
// 获取请求 ID由 requestid 中间件设置)
requestID := ""
requestID = ""
if rid := c.Locals(constants.ContextKeyRequestID); rid != nil {
requestID = rid.(string)
}

View File

@@ -2,7 +2,9 @@ package middleware
import (
"context"
"strconv"
"github.com/break/junhong_cmp_fiber/pkg/auditcontext"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
"github.com/break/junhong_cmp_fiber/pkg/logger"
@@ -37,6 +39,27 @@ func SetUserContext(ctx context.Context, info *UserContextInfo) context.Context
if info.SubordinateShopIDs != nil {
ctx = context.WithValue(ctx, constants.ContextKeySubordinateShopIDs, info.SubordinateShopIDs)
}
actorKind := constants.AuditActorAccount
actorID := info.UserID
source := constants.AuditSourceAdminAPI
if info.UserType == constants.UserTypePersonalCustomer {
actorKind = constants.AuditActorPersonalCustomer
source = constants.AuditSourcePersonalAPI
if info.CustomerID > 0 {
actorID = info.CustomerID
}
}
var shopID, enterpriseID *uint
if info.ShopID > 0 {
shopID = &info.ShopID
}
if info.EnterpriseID > 0 {
enterpriseID = &info.EnterpriseID
}
ctx = auditcontext.With(ctx, auditcontext.Context{
ActorKind: actorKind, ActorID: strconv.FormatUint(uint64(actorID), 10), ActorName: info.Username,
ActorShopID: shopID, ActorEnterpriseID: enterpriseID, Source: source,
})
return ctx
}

View File

@@ -75,6 +75,7 @@ func BuildDocHandlers() *bootstrap.Handlers {
ClientWechat: app.NewClientWechatHandler(nil, nil, nil),
SuperAdmin: admin.NewSuperAdminHandler(nil),
SystemConfig: admin.NewSystemConfigHandler(nil, nil),
Audit: admin.NewAuditHandler(nil, nil),
WeCom: admin.NewWeComHandler(nil, nil),
AgentOpenAPI: openapiHandler.NewHandler(nil, nil),
}

View File

@@ -20,6 +20,9 @@ var forbiddenFragments = []string{
// IsForbiddenField 判断字段是否禁止进入普通日志、审计或外部交互摘要。
func IsForbiddenField(key string) bool {
normalized := strings.ToLower(strings.NewReplacer("-", "_", ".", "_").Replace(key))
if normalized == "credentials_configured" {
return false
}
for _, fragment := range forbiddenFragments {
if strings.Contains(normalized, fragment) {
return true