feat(版本): 完善研发计划与预警已读
关键改动: - 增加版本表单、发布校验和调研方向进度规则 - 扩展小宝预警已读状态、风险签名和今日证据 - 补充组长权限、加班查看范围、活动记录与相关测试 Co-Authored-By: Codex GPT-5 <codex@openai.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { VersionWithContext } from './derive';
|
||||
import type { XiaobaoRiskInsight } from './xiaobao-risk-cache';
|
||||
import type { XiaobaoVersionRisk } from './xiaobao-risk';
|
||||
import { buildRiskInsightDisplaySignature, normalizeRiskInsightDisplaySignature } from './xiaobao-risk-ai';
|
||||
import { WORK_HOURS } from './work-hours';
|
||||
|
||||
const UNFINISHED_VERSION_STATUSES = new Set(['planned', 'developing', 'paused']);
|
||||
@@ -28,6 +29,13 @@ export interface XiaobaoWarningRiskListFilter {
|
||||
|
||||
export type RiskScoreTone = 'danger' | 'warn' | 'ok';
|
||||
|
||||
export interface XiaobaoWarningReadState {
|
||||
userId: string;
|
||||
versionId: string;
|
||||
signature: string;
|
||||
readAt: string;
|
||||
}
|
||||
|
||||
export function filterXiaobaoWarningVersions(
|
||||
versions: VersionWithContext[],
|
||||
filter: XiaobaoWarningVersionFilter,
|
||||
@@ -58,6 +66,52 @@ export function getXiaobaoWarningRiskCount(risks: XiaobaoVersionRisk[]): number
|
||||
return filterXiaobaoRiskWarnings(risks).length;
|
||||
}
|
||||
|
||||
export function getXiaobaoWarningUpdateSignature(risk: XiaobaoVersionRisk): string {
|
||||
return buildRiskInsightDisplaySignature(risk);
|
||||
}
|
||||
|
||||
export function isXiaobaoWarningUpdated(
|
||||
risk: XiaobaoVersionRisk,
|
||||
readStates: XiaobaoWarningReadState[],
|
||||
userId?: string,
|
||||
): boolean {
|
||||
if (!userId) return false;
|
||||
if (risk.aiInsightUpdating) return false;
|
||||
const currentSignature = getXiaobaoWarningUpdateSignature(risk);
|
||||
const readState = readStates.find((item) => item.userId === userId && item.versionId === risk.versionId);
|
||||
const readSignature = readState?.signature
|
||||
? normalizeRiskInsightDisplaySignature(readState.signature) ?? readState.signature
|
||||
: undefined;
|
||||
return readSignature !== currentSignature;
|
||||
}
|
||||
|
||||
export function getXiaobaoWarningUnreadUpdateCount(
|
||||
risks: XiaobaoVersionRisk[],
|
||||
readStates: XiaobaoWarningReadState[],
|
||||
userId?: string,
|
||||
): number {
|
||||
return risks.filter((risk) => isXiaobaoWarningUpdated(risk, readStates, userId)).length;
|
||||
}
|
||||
|
||||
export function markXiaobaoWarningRead(
|
||||
readStates: XiaobaoWarningReadState[],
|
||||
userId: string,
|
||||
risk: XiaobaoVersionRisk,
|
||||
readAt: string,
|
||||
): XiaobaoWarningReadState[] {
|
||||
if (risk.aiInsightUpdating) return readStates;
|
||||
const item: XiaobaoWarningReadState = {
|
||||
userId,
|
||||
versionId: risk.versionId,
|
||||
signature: getXiaobaoWarningUpdateSignature(risk),
|
||||
readAt,
|
||||
};
|
||||
return [
|
||||
item,
|
||||
...readStates.filter((row) => row.userId !== userId || row.versionId !== risk.versionId),
|
||||
];
|
||||
}
|
||||
|
||||
export function getRiskScoreTone(score: number): RiskScoreTone {
|
||||
if (score >= 75) return 'danger';
|
||||
if (score >= 55) return 'warn';
|
||||
|
||||
Reference in New Issue
Block a user