|
|
@@ -105,6 +105,36 @@ public class S8ManualReportService : ITransient
|
|
|
_logger = logger;
|
|
|
}
|
|
|
|
|
|
+ // S8-AUTO-WATCH-DEPT-ZERO-AUDIT-1(P0-B-4):自动建单将写入 dept=0 时打 warning,行为不变。
|
|
|
+ // 触发:raw 部门字段为 null 或 <=0。两条自动建单路径(CreateFromWatchAsync / CreateFromHitAsync)
|
|
|
+ // 当前都用 `?? 0` 兜底;本助手只观测、不阻断、不替换值。部门派生器属 P2,不在本批。
|
|
|
+ private void WarnIfAutoWatchZeroDept(
|
|
|
+ string path,
|
|
|
+ long? ruleId,
|
|
|
+ string? ruleCode,
|
|
|
+ string? moduleCode,
|
|
|
+ string? sceneCode,
|
|
|
+ string? exceptionTypeCode,
|
|
|
+ string? sourceObjectType,
|
|
|
+ string? sourceObjectId,
|
|
|
+ string? relatedObjectCode,
|
|
|
+ string? dedupKey,
|
|
|
+ long? rawOccurrenceDeptId,
|
|
|
+ long? rawResponsibleDeptId,
|
|
|
+ long finalOccurrenceDeptId,
|
|
|
+ long finalResponsibleDeptId,
|
|
|
+ long tenantId,
|
|
|
+ long factoryId,
|
|
|
+ string? exceptionCode)
|
|
|
+ {
|
|
|
+ var occMissing = !rawOccurrenceDeptId.HasValue || rawOccurrenceDeptId.Value <= 0;
|
|
|
+ var respMissing = !rawResponsibleDeptId.HasValue || rawResponsibleDeptId.Value <= 0;
|
|
|
+ if (!occMissing && !respMissing) return;
|
|
|
+ _logger.LogWarning(
|
|
|
+ "s8_auto_watch_zero_dept_detected path={Path} ruleId={RuleId} ruleCode={RuleCode} moduleCode={ModuleCode} sceneCode={SceneCode} exceptionTypeCode={ExceptionTypeCode} sourceObjectType={SourceObjectType} sourceObjectId={SourceObjectId} relatedObjectCode={RelatedObjectCode} dedupKey={DedupKey} rawOccurrenceDeptId={RawOccDept} rawResponsibleDeptId={RawRespDept} finalOccurrenceDeptId={FinalOccDept} finalResponsibleDeptId={FinalRespDept} tenantId={TenantId} factoryId={FactoryId} exceptionCode={ExceptionCode}",
|
|
|
+ path, ruleId, ruleCode, moduleCode, sceneCode, exceptionTypeCode, sourceObjectType, sourceObjectId, relatedObjectCode, dedupKey, rawOccurrenceDeptId, rawResponsibleDeptId, finalOccurrenceDeptId, finalResponsibleDeptId, tenantId, factoryId, exceptionCode);
|
|
|
+ }
|
|
|
+
|
|
|
// S8-REPORTER-IDSPACE-FIX-1(P0-B-1):把当前登录 SysUser.Id 反查 EmployeeMaster.RecID。
|
|
|
// 用于 reporter_id idspace 与 assignee_id / verifier_id 对齐。
|
|
|
// 协议:sys_user_id + factory_ref_id 双键命中;EmployeeMaster.tenant_id 与 SysUser.TenantId 历史错位 →
|
|
|
@@ -368,6 +398,26 @@ public class S8ManualReportService : ITransient
|
|
|
RelatedObjectCode = hit.RelatedObjectCode
|
|
|
};
|
|
|
|
|
|
+ // S8-AUTO-WATCH-DEPT-ZERO-AUDIT-1(P0-B-4):raw dept 缺失时打 warning,行为不变。
|
|
|
+ WarnIfAutoWatchZeroDept(
|
|
|
+ path: nameof(CreateFromWatchAsync),
|
|
|
+ ruleId: hit.SourceRuleId,
|
|
|
+ ruleCode: null,
|
|
|
+ moduleCode: resolvedModule,
|
|
|
+ sceneCode: S8SceneCode.S2,
|
|
|
+ exceptionTypeCode: "EQUIP_FAULT",
|
|
|
+ sourceObjectType: null,
|
|
|
+ sourceObjectId: null,
|
|
|
+ relatedObjectCode: hit.RelatedObjectCode,
|
|
|
+ dedupKey: null,
|
|
|
+ rawOccurrenceDeptId: hit.OccurrenceDeptId,
|
|
|
+ rawResponsibleDeptId: hit.ResponsibleDeptId,
|
|
|
+ finalOccurrenceDeptId: entity.OccurrenceDeptId,
|
|
|
+ finalResponsibleDeptId: entity.ResponsibleDeptId,
|
|
|
+ tenantId: entity.TenantId,
|
|
|
+ factoryId: entity.FactoryId,
|
|
|
+ exceptionCode: entity.ExceptionCode);
|
|
|
+
|
|
|
await _rep.AsTenant().UseTranAsync(async () =>
|
|
|
{
|
|
|
entity = await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
|
|
|
@@ -457,6 +507,26 @@ public class S8ManualReportService : ITransient
|
|
|
SourceObjectId = hit.SourceObjectId
|
|
|
};
|
|
|
|
|
|
+ // S8-AUTO-WATCH-DEPT-ZERO-AUDIT-1(P0-B-4):raw dept 缺失时打 warning,行为不变。
|
|
|
+ WarnIfAutoWatchZeroDept(
|
|
|
+ path: nameof(CreateFromHitAsync),
|
|
|
+ ruleId: hit.SourceRuleId,
|
|
|
+ ruleCode: hit.SourceRuleCode,
|
|
|
+ moduleCode: resolvedModule,
|
|
|
+ sceneCode: effectiveScene,
|
|
|
+ exceptionTypeCode: hit.ExceptionTypeCode,
|
|
|
+ sourceObjectType: hit.SourceObjectType,
|
|
|
+ sourceObjectId: hit.SourceObjectId,
|
|
|
+ relatedObjectCode: hit.RelatedObjectCode,
|
|
|
+ dedupKey: hit.DedupKey,
|
|
|
+ rawOccurrenceDeptId: hit.OccurrenceDeptId,
|
|
|
+ rawResponsibleDeptId: hit.ResponsibleDeptId,
|
|
|
+ finalOccurrenceDeptId: entity.OccurrenceDeptId,
|
|
|
+ finalResponsibleDeptId: entity.ResponsibleDeptId,
|
|
|
+ tenantId: entity.TenantId,
|
|
|
+ factoryId: entity.FactoryId,
|
|
|
+ exceptionCode: entity.ExceptionCode);
|
|
|
+
|
|
|
await _rep.AsTenant().UseTranAsync(async () =>
|
|
|
{
|
|
|
entity = await _rep.AsInsertable(entity).ExecuteReturnEntityAsync();
|