diff --git a/app/api/evaluation_points/rule-groups.ts b/app/api/evaluation_points/rule-groups.ts index 5f8a9e3..ee4d4aa 100644 --- a/app/api/evaluation_points/rule-groups.ts +++ b/app/api/evaluation_points/rule-groups.ts @@ -740,50 +740,114 @@ export async function updateRuleGroup(id: string, data: RuleGroupCreateUpdateDto } /** - * 删除评查点分组 + * 删除评查点分组(增强版 - 安全的阻止删除策略) + * + * 删除策略: + * - 如果分组下有子分组,拒绝删除,提示用户先删除子分组 + * - 如果分组下有评查点,拒绝删除,提示用户先删除或移动评查点 + * - 只有空分组才能被删除 + * * @param id 分组ID * @param token JWT token (可选) * @returns 删除结果 */ -export async function deleteRuleGroup(id: string, token?: string): Promise<{success: boolean; error?: string}> { +export async function deleteRuleGroup(id: string, token?: string): Promise<{success: boolean; error?: string; details?: { hasChildren: boolean; hasPoints: boolean; childCount?: number; pointCount?: number }}> { try { - // 1. 首先获取分组信息,判断是一级还是二级分组 + // ========== 1. ID验证 ========== + + if (!id) { + return { success: false, error: '分组ID不能为空' }; + } + + // 验证分组是否存在 const groupResponse = await getRuleGroup(id, token); - if (groupResponse.error) { - return { success: false, error: groupResponse.error }; + if (groupResponse.error || !groupResponse.data) { + return { success: false, error: '分组不存在或无法访问' }; } const group = groupResponse.data; - if (!group) { - return { success: false, error: '未找到指定分组' }; - } - // 2. 如果是一级分组(顶级分组,pid为NULL或'0'),需要先删除所有子分组 - if (!group.pid || group.pid === '0' || group.pid === null) { - // 获取所有子分组 + // ========== 2. 检查是否有子分组(一级分组专用) ========== + + let hasChildren = false; + let childCount = 0; + + // 如果是一级分组,检查是否有子分组 + if (!group.pid || group.pid === '0') { const childGroupsResponse = await getChildGroups(id, token); + if (childGroupsResponse.error) { - return { success: false, error: childGroupsResponse.error }; + return { + success: false, + error: `检查子分组时出错: ${childGroupsResponse.error}` + }; } const childGroups = childGroupsResponse.data || []; - - // 遍历删除每个子分组 - for (const childGroup of childGroups) { - const deleteChildResult = await deleteChildGroup(childGroup.id, token); - if (!deleteChildResult.success) { - return deleteChildResult; - } + childCount = childGroups.length; + hasChildren = childCount > 0; + + if (hasChildren) { + return { + success: false, + error: `该分组下存在 ${childCount} 个子分组,请先删除所有子分组后再删除此分组。`, + details: { + hasChildren: true, + hasPoints: false, + childCount + } + }; } } - // 3. 删除分组下的所有评查点 - const deletePointsResult = await deleteEvaluationPointsByGroupId(id, token); - if (!deletePointsResult.success) { - return deletePointsResult; + // ========== 3. 检查是否有关联的评查点 ========== + + const pointsParams: PostgrestParams = { + select: 'id', + filter: { + 'evaluation_point_groups_id': `eq.${id}` + }, + limit: 1, // 只需要知道是否存在,不需要获取所有数据 + token + }; + + const pointsResponse = await postgrestGet>>( + 'evaluation_points', + pointsParams + ); + + let hasPoints = false; + let pointCount = group.ruleCount || 0; + + if (pointsResponse.error) { + return { + success: false, + error: `检查关联评查点时出错: ${pointsResponse.error}` + }; } - // 4. 最后删除分组本身 + if (pointsResponse.data) { + if ('code' in pointsResponse.data && pointsResponse.data.data) { + hasPoints = Array.isArray(pointsResponse.data.data) && pointsResponse.data.data.length > 0; + } else if (Array.isArray(pointsResponse.data)) { + hasPoints = pointsResponse.data.length > 0; + } + } + + if (hasPoints) { + return { + success: false, + error: `该分组下存在 ${pointCount} 个评查点,请先删除或移动所有评查点后再删除此分组。`, + details: { + hasChildren: false, + hasPoints: true, + pointCount + } + }; + } + + // ========== 4. 执行删除操作 ========== + const response = await postgrestDelete>('evaluation_point_groups', { filter: { 'id': `eq.${id}` @@ -792,21 +856,29 @@ export async function deleteRuleGroup(id: string, token?: string): Promise<{succ }); if (response.error) { - return { success: false, error: response.error }; + return { success: false, error: `删除失败: ${response.error}` }; } - return { success: true }; + return { + success: true, + details: { + hasChildren: false, + hasPoints: false + } + }; } catch (error) { console.error('删除评查点分组失败:', error); - return { - success: false, + return { + success: false, error: error instanceof Error ? error.message : '删除评查点分组失败' }; } } /** - * 删除子分组及其相关数据 + * 删除子分组及其相关数据(级联删除) + * + * @deprecated 当前采用阻止删除策略,此函数暂不使用 * @param id 子分组ID * @param token JWT token (可选) * @returns 删除结果 @@ -842,7 +914,9 @@ async function deleteChildGroup(id: string, token?: string): Promise<{success: b } /** - * 删除指定分组下的所有评查点 + * 删除指定分组下的所有评查点(级联删除) + * + * @deprecated 当前采用阻止删除策略,此函数暂不使用 * @param groupId 分组ID * @param token JWT token (可选) * @returns 删除结果