/** * 立项确认防双击:同步 in-flight 锁 + 提交态文案。 * React state(bootstrapId / submitting)不能单独阻止并发入口。 */ export type CreateProjectInFlightLock = { current: boolean }; export type CreateProjectSubmitPhase = 'creating' | 'syncing_members'; /** 入口立即抢锁;已在途返回 false,调用方必须直接 return。 */ export function beginCreateProjectSubmit(lock: CreateProjectInFlightLock): boolean { if (lock.current) return false; lock.current = true; return true; } /** finally 中释放,失败后允许串行幂等重试。 */ export function endCreateProjectSubmit(lock: CreateProjectInFlightLock): void { lock.current = false; } export function resolveCreateProjectSubmitPhase( bootstrapProjectId: number | null, ): CreateProjectSubmitPhase { return bootstrapProjectId != null && bootstrapProjectId > 0 ? 'syncing_members' : 'creating'; } export function createProjectSubmitButtonLabel( submitting: boolean, phase: CreateProjectSubmitPhase | null, ): string { if (!submitting) return '确认立项并创建会话'; if (phase === 'syncing_members') return '同步成员中'; return '立项中'; } export function shouldBlockCreateProjectClose(submitting: boolean): boolean { return submitting; } /** Software projects must not clone the medical 7-template pack. */ export function shouldCloneMedicalTemplates(productDomain: string | undefined): boolean { return productDomain !== 'non_medical_software'; }